当前位置: 首页 > news >正文

Codeforces Beta Round #96 (Div. 1) C. Logo Turtle —— DP

题目链接:http://codeforces.com/contest/132/problem/C


 

C. Logo Turtle
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A lot of people associate Logo programming language with turtle graphics. In this case the turtle moves along the straight line and accepts commands "T" ("turn around") and "F" ("move 1 unit forward").

You are given a list of commands that will be given to the turtle. You have to change exactly n commands from the list (one command can be changed several times). How far from the starting point can the turtle move after it follows all the commands of the modified list?

Input

The first line of input contains a string commands — the original list of commands. The string commands contains between 1 and 100 characters, inclusive, and contains only characters "T" and "F".

The second line contains an integer n (1 ≤ n ≤ 50) — the number of commands you have to change in the list.

Output

Output the maximum distance from the starting point to the ending point of the turtle's path. The ending point of the turtle's path is turtle's coordinate after it follows all the commands of the modified list.

Examples
input
FT
1
output
2
input
FFFTFFF
2
output
6
Note

In the first example the best option is to change the second command ("T") to "F" — this way the turtle will cover a distance of 2 units.

In the second example you have to change two commands. One of the ways to cover maximal distance of 6 units is to change the fourth command and first or last one.

 

 

 

题解:

方法一(四维dp):

1.dp[i][j][dir][dis]表示:执行到第i个指令,修改了j个指令,前进方向为dir,且到达了dis的地方的情况是否存在。其值为0或1。

2.枚举已有状态,推出下一步状态。(与常见的dp不同,常见的dp为枚举可能的状态,然后看他能从那些状态转移过来)。

3.由于结束点可能在左边,即距离为负数,为了防止溢出,将起始点往右移100。

类似的做法的题:http://blog.csdn.net/dolfamingo/article/details/73903530



易错点:

写成dp[i][j][dir][dis] 或者dp[i][j][dis][dir]都可以,但是写成dp[dir][i][j][dis] 或者dp[dis][i][j][dir]等等就不行了,因为枚举的顺序不对。递推必须自底向上,如果“底”都没推出来,那“上”自然也推不出来了。



学习之处:

一:目前了解到的递推式DP有两种:

1.当前状态(可能不存在)能从哪些状态转移过来。 被赋值的状态是当前状态。

 2.当前状态(已存在)能推出哪些状态。 被赋值的状态是被推出来的状态。


二:

当设定的k维dp不好递推时,如果再加多一维(这一维是数值,且范围很小)仍不会超时,那么就可以改写成k+1维的dp,这样所有可能的状态都通过dp数组的下标体现出来了,所以要做的就是:递推出存在的状态,然后在这些状态中找出最优结果。


 

四维DP:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const double eps = 1e-6;
 5 const int INF = 2e9;
 6 const LL LNF = 9e18;
 7 const int mod = 1e9+7;
 8 const int maxn = 100+10;
 9 
10 int n, m, dp[110][55][2][210];
11 char s[maxn];
12 
13 void init()
14 {
15     scanf("%s%d",s+1, &m);
16     n = strlen(s+1);
17 
18     dp[0][0][0][100] = 1;    //起始点平移到100,防止下标溢出
19     for(int i = 0; i<n; i++)
20     for(int j = 0; j<=m; j++)  //这样枚举,一个指令最多只能修改一次
21     for(int dir = 0; dir<2; dir++)
22     for(int dis = 0; dis<=200; dis++)
23     {
24         if(!dp[i][j][dir][dis]) continue;
25 
26         dp[i+1][j+(s[i+1]!='F')][dir][dis+(dir?-1:1)] = 1;
27         dp[i+1][j+(s[i+1]!='T')][!dir][dis] = 1;
28     }
29 }
30 
31 void solve()
32 {
33     int ans = -INF;
34     for(int j = m; j>=0; j -= 2)  //一个指令可以修改多次
35     for(int dir = 0; dir<2; dir++)
36     for(int dis = 0; dis<=200; dis++)
37     if(dp[n][j][dir][dis])
38         ans = max(ans, abs(100-dis));     //与100的距离,即为实际距离
39     cout<<ans<<endl;
40 }
41 
42 int main()
43 {
44     init();
45     solve();
46 }
View Code


三维DP:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const double eps = 1e-6;
 5 const int INF = 2e9;
 6 const LL LNF = 9e18;
 7 const int mod = 1e9+7;
 8 const int maxn = 100+10;
 9 
10 char s[105];
11 int n,m, dp[110][55][2];
12 
13 int main()
14 {
15     scanf("%s%d",s+1,&m);
16     n = strlen(s+1);
17     for(int i = 0; i<=n; i++)
18     for(int j = 0; j<=m; j++)
19     for(int k = 0; k<2; k++)
20         dp[i][j][k] = -INF;
21 
22     dp[0][0][0] = dp[0][0][1] = 0;
23     for(int i = 0; i<n; i++)
24     for(int j = 0; j<=m; j++)
25     for(int k = 0; k<2; k++)
26     {
27         dp[i+1][j+(s[i+1]!='F')][k] = max(dp[i+1][j+(s[i+1]!='F')][k],dp[i][j][k]+(k?1:-1));
28         dp[i+1][j+(s[i+1]!='T')][!k] = max(dp[i+1][j+(s[i+1]!='T')][!k],dp[i][j][k]);
29     }
30 
31     int ans = -INF;
32     for (int j = m; j>=0; j -= 2)
33         ans = max(ans, max(dp[n][j][0], dp[n][j][1]));
34 
35     printf("%d\n",ans);
36 }
View Code

 

转载于:https://www.cnblogs.com/DOLFAMINGO/p/7538653.html

相关文章:

  • 【RQNOJ】460 诺诺的队列
  • JS的join方法
  • java selenium (十四) 处理Iframe 中的元素
  • 日志架构
  • 各种定位方式
  • JAVA个人小程序GUI篇-收银(标签、按钮、复选框、下拉标、文本域、表格······)...
  • [bzoj2957]楼房重建
  • 杨辉三角的几种方法
  • 标题四
  • 3种上传图片并实现预览的方法
  • 暑假小集训
  • [无线路由] “免费”斐讯K2路由器刷OpenWRT(实战MWAN多宽带网速叠加)
  • 静态变量
  • Java字节数组和16进制字符串的互相转化
  • 多进程与多线程的区别
  • AHK 中 = 和 == 等比较运算符的用法
  • download使用浅析
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript对象详解
  • mongodb--安装和初步使用教程
  • SpriteKit 技巧之添加背景图片
  • 笨办法学C 练习34:动态数组
  • 不上全站https的网站你们就等着被恶心死吧
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 理解在java “”i=i++;”所发生的事情
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 通过npm或yarn自动生成vue组件
  • 为什么要用IPython/Jupyter?
  • 一天一个设计模式之JS实现——适配器模式
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​MySQL主从复制一致性检测
  • ​马来语翻译中文去哪比较好?
  • ​一些不规范的GTID使用场景
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #、%和$符号在OGNL表达式中经常出现
  • #LLM入门|Prompt#3.3_存储_Memory
  • #大学#套接字
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (70min)字节暑假实习二面(已挂)
  • (day6) 319. 灯泡开关
  • (JS基础)String 类型
  • (LeetCode) T14. Longest Common Prefix
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (简单) HDU 2612 Find a way,BFS。
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (原)本想说脏话,奈何已放下
  • (转)h264中avc和flv数据的解析
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .Net Memory Profiler的使用举例
  • .net web项目 调用webService