Gym 100712D Alternating Strings 动态规划
来源:互联网 发布:华为财务共享中心 知乎 编辑:程序博客网 时间:2024/05/19 22:55
题意:给你一个n值一个k值,一个长度为n的01串,现在要求你切割原串,使新形成的每个子串都满足,长度不超过k,且任何子串都不是完全交替的01串,利于010101就是完全交替的01串,而00101010就不是,问你最少需要切几刀。
题解:完全照着官方题解来的,自己看了几个小时也没看明白,问巨巨们都是扫一眼就告诉我怎么做,然而即便是这样我还是无法理解每一步程序究竟是什么意思,后来跟phy讨论了半天,慢慢慢慢才搞懂了。
虽然这貌似在大神们眼里是个很简单的dp,但是既然卡了我这么久,那还是好好理下思路。
首先,题解里的外循环i是从后往前推的,然后内循环是从第i位向后推k位。当然这两个循环是完全可以调头的(i从前往后,内循环从i往前推k位)这些都无所谓。
dp[i]代表的是从第i位开始往后的串在满足条件的情况下切完后所形成的子串数目。
下面就开始讲解dp的递推过程。
假设一个串11100,k为3,那么我们从右往左推首先初始化dp[5]=0,因为s下标从0到n-1,所以相当于第5位没东西,自然没有一个串。
接下来进入循环。
I=4,则j从4开始到min(s.len,i+l-1)即第4位,当i==j时,dp[4]=dp[5]+1;
那么这个dp[5]+1是什么意思呢,我们知道dp[5]=0代表第五位没有串。那么dp[5]+1即,在第五位的基础上加了一个串进去,也就是s[4]。那么此时dp[4]=1就代表有了一个合法的串。
I=3,则j从3开始到min(s.len,i+l-1)即第4位,先是dp[3]=dp[4]+1=2,即在段s[4]外加了一个段s[3].
就是这样 0 0,红色的零就是我们当前加进去的串。然后当j=4时,因为s[j]=s[j-1]=0,所以,s[j]与s[j-1]所构成的串为合法串,那么它们俩就可以单独构成一个串。也就是说可以合起来放在第5位外面,即0 0,这样dp[i]就可以取1。取最优解。
I=2时,j从2到4,同样dp[2]=dp[3]+1=2,代表这样,1 0 0,而当j=3时,因为s[j]!=s[j-1],所以从s[j]与s[j-1]所构成的串是不合法的,所以我们不能把他们俩组合起来加在第4位的外面(也就是这样1 0 0),所以不进行比较,而当j=4时,因为s[j]==s[j-1]=0,此时dp[i]=min(dp[i],dp[j+1]+1)也就是把100连起来放在了第5位外面,拿这种情况(100)跟(100)相比,取最优解(100)dp[2]=1;
以下红色都为当前i到j之间的串。
I=1时,
J=1先是这样1 1 0. . .
J=2 11 0 . . .
J=3 1 1 0 . . .(因为前面出现过11,所以0可以加在11后面形成合法串)
取最优解 1 1 0 . . .
I=0时
J = 0 1 1 1 . . .
J = 1 1 1 1 ....
J= 2 1 1 1 ....
取最优解
那么最后dp[0]即为最少段数,dp[0]-1就是最少切割次数。
果然,蒟蒻就要多写写尽量写完整才能把思路理清。
代码(其实就是官方题解):
#include<bits/stdc++.h>#define MEM(a,x) memset(a,x,sizeof(a));#define MEMINF(a) memset(a,0x3f,sizeof(a));using namespace std;typedef long long LL;const int MAXN=205;const int INF=0x3f3f3f3f;const int MOD=1000000007;int dp[MAXN];int main() { int T; cin>>T; while (T--) { int n,k; string s; cin>>n>>k>>s; dp[n]=0; for (int i=s.size()-1; i>=0; i--) { bool flag=true; dp[i]=INF; for (int j = i; j <= i + k - 1 && j < s.size(); ++j) { if ( j > i && s[j] == s[j - 1]) flag = false; if (i == j || flag == false ) dp[i]= min(dp[i], 1 + dp[j + 1]); } } printf("%d\n",dp[0]-1);}}
- Gym 100712D Alternating Strings 动态规划
- 【动态规划】Alternating Strings Gym
- Gym 100712D Alternating Strings (dp)
- amman D.Alternating Strings
- GYM 100712 L.Alternating Strings II(dp+线段树)
- 2015 ACM Amman Collegiate Programming Contest D.Alternating Strings【Dp】
- 区间dp Gym100712D Alternating Strings
- GYM-100952-Special Palindrome【动态规划】
- 动态规划D
- HDU6170 Two strings(动态规划)
- Codeforces 344D - Alternating Current
- [预处理优化][动态规划]D
- codeforces 229/D 动态规划
- 费波纳契数d动态规划实现
- Codeforces 611D 动态规划
- 动态规划—Problem D
- Gym 100703F Game of words 动态规划
- CodeForces - 344D Alternating Current (模拟题)
- 欢迎使用CSDN-markdown编辑器
- linux 下ftp命令使用
- lua第一个运行实例
- 安装win10 以及 office2016遇到的问题
- 数据结构学习笔记--队列
- Gym 100712D Alternating Strings 动态规划
- ViewPagerIndicator的简单实用
- poj 3252 Round Numbers(数位dp)
- 算法三(回溯算法)
- JVM类加载机制—加载的顺序问题
- android json解析及简单例子
- GestureDetector 手势识别器
- JAVA EE 自学路线
- js的继承问题