UVALive

来源:互联网 发布:广电网络整合最新消息 编辑:程序博客网 时间:2024/06/05 08:15

给你一个字符串,让你把它压缩,比如gogogo可以压缩成3(go),letsgogogoletsgogogo可以压缩成2(lets3(go)),然后问你压缩后的最短长度。

典型的区间dp

递推方程:dp[j][i]=min(dp[j][i],dp[j][k]+dp[k+1][i]);

dp[j][i]=min(dp[j][i],dp[j][j+k-1]+2+get(tmp));

#include <stdio.h>#include <string.h>#include <algorithm>#include <string.h>#include <iostream>#include <sstream>using namespace std;const int Nmax=1505;  int dp[Nmax][Nmax];  char s[10005];int check(int be,int en,int k)//判断i到j这一段区间能否分为长度为k的若干个区间 {if((en-be+1)%k) return 0;for(int i=be+k;i<=en;i+=k){for(int j=0;j<k;j++){if(s[i+j]!=s[be+j])return 0;}}return (en-be+1)/k;}int get(int x) //返回一个数的位数 {      if (x >= 0 && x <= 9) return 1;      else if (x >= 10 && x <= 99) return 2;      else return 3;  }  int main(){int t;cin>>t;while(t--){scanf("%s",s);int temp,n=strlen(s);memset(dp,0x3f3f3f3f,sizeof dp);for(int i=0;i<n;i++)dp[i][i]=1;for(int i=0;i<n;i++){for(int j=i-1;j>=0;j--){for(int k=j;k<i;k++)//可以分成两个子区间的和 dp[j][i]=min(dp[j][i],dp[j][k]+dp[k+1][i]);for(int k=1;k<=(i-j+1)/2;k++) //把区间分为长度为k的tmp块 {int tmp=check(j,i,k);//如果所求区间可以分为tmp块 if(tmp) dp[j][i]=min(dp[j][i],dp[j][j+k-1]+2+get(tmp));}}}printf("%d\n",dp[0][n-1]);}return 0;}


原创粉丝点击