题目大意:
给你长度为N的一个01字符串,要求我们将其割分成若干个连续子序列,使得每个子序列的长度都不超过K,而且保证每个子序列,要么是单独的一个数,要么是非01间差排列的子序列(01间差排列:1010,010101,.....................)。
思路:
观察到数据范围不是很大,我们考虑直接O(n*k)去Dp即可,设定Dp【i】表示以位子i结尾,最少要割分的次数。
那么有:
①Dp【i】=min(Dp【i】,Dp【j】+1),需要保证从j+1到位子i的排列是可行方案。
②Dp【i】=min(Dp【i-1】+1,Dp【i】);
那么对于是否可行的方案判定,其实很简单,我们倒序扫从i-1到0,如果出现了连续两个1或者连续的两个0.那么就是可行方案。
拿个flag标记一下就行。
具体参考代码很好理解.
Ac代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
char a[1500];
int dp[1500];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)dp[i]=0x3f3f3f3f;
dp[0]=0;
scanf("%s",a+1);
for(int i=1;i<=n;i++)
{
int flag=0;
dp[i]=min(dp[i],dp[i-1]+1);
for(int j=i-1;j>=1;j--)
{
if(a[j]==a[j+1])flag=1;
if(i-j+1<=k)
{
if(flag==1)
dp[i]=min(dp[i],dp[j-1]+1);
}
else break;
}
}
printf("%d\n",dp[n]-1);
}
}