2015 ACM Amman Collegiate Programming Contest D.Alternating Strings【Dp】

来源:互联网 发布:网络语鬼畜什么意思 编辑:程序博客网 时间:2024/06/02 02:14


题目大意:


给你长度为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);    }}





阅读全文
0 0
原创粉丝点击