玲珑OJ 1070 (区间DP)

1070 - Generate String

Time Limit:1s Memory Limit:1024MByte

Submissions:106Solved:28

DESCRIPTION

Mr. Van wants to generate a sequence of characters starting from an empty string using the following method.

Initially, the original S0 is an empty string. In each step, Mr. Van will split an original string Sk into two continuous string Sub1 and Sub2. Either of them may be empty. And add a string T, which consists of only a single kind of character, to concatenate them. So, Sk+1=Sub1+T+Sub2.

Your task is to help Mr. Van generating a given string S using minimum steps.

Take S='aabbaab' for example.

  • Initially : S0=''
  • Step 1 : S1='aaaa'
  • Step 2 : S2='aabbaa'
  • Step 3 : S3='aabbaab'


    So, you need 3 steps.
INPUT
The first line is a single integer TT, indicating the number of test cases.

题意;操作使一个空字符串生成一个字符序列。你可以把一个字符串切成两个字符串 ,使Sk + 1 = Sub1 + T + Sub2,字符串sub1,sub2可以为空,并添加字符串T,T只由一种字符组成,问你最小操作次数。

区间DP,状态dp【i】【j】,表示组成原字符串s【i~j】的最小操作次数。
状态转移: dp【i】【j】=min(dp【i+1】【j】+1,(前提;s【i】==s【k】)dp【i+1】【k】+dp【k+1】【j】);

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <queue>
#define mem(p,k) memset(p,k,sizeof(p));
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define inf 0x6fffffff
#define LL long long
#define MAXN 20000
using namespace std;
char s[400];
int dp[220][220];
int main(){
    int t;
    cin>>t;
    while(t--){
        scanf("%s",s+1);
        int len=strlen(s+1);
        for(int i=1;i<=len;i++)dp[i][i]=1;
        for(int i=len-1;i>=1;i--){
            for(int j=i+1;j<=len;j++){
                dp[i][j]=dp[i+1][j]+1;
                for(int k=i+1;k<=j;k++)
                     if(s[i]==s[k])dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j]);
            }
        }
        printf("%d\n",dp[1][len]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值