uva1351 dp

这题说的是给了 一个串 然后 比如 aaaaabbbbbbcdddd 可以化成5(a)6(b)c4(d) 这样的串明显 长度更短了 , 请 计算出使得这个串最短的 长度是多少,

dp[i][j] 表示 从字符串i到j 之间的最短的 长度, 然后 先预处理出来 可以简化的 区间 

然后 枚举每个区间 去求得最小值

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std;
const int maxn =205;
int dp[maxn][maxn];
char str[maxn];
void inti(int n){
   for(int i=0; i<n; ++i)
    for(int j=i; j<n; ++j)
       dp[i][j]=j-i+1;
}
bool cmp(int s, int t, int num, int n){
    for(int i=0; i<num; ++i)
         if(str[s+i]!=str[t+i]||t+i>=n) return false;
    return true;
}
int ccc(int v){
   int ans=0;
   while(v>0) {
     ans++;
     v/=10;
   }
   return ans;
}
int main()
{
     int cas;
     scanf("%d",&cas);
     for(int cc=1; cc<=cas; ++cc){
          scanf("%s",str);
          int n=strlen(str);
          int ok=0;
          inti(n);
          for(int i=1; i<=n; ++i){
              for(int j=0; j+i<n; j++){
                   ok=0;
                   for(int k=j+i; k<n; k+=i){
                        if(cmp(j,k,i,n)==true) ok++;
                        else break;
                   }
                   for(int k=0; k<i-1; ++k)
                   dp[j][j+i-1]=min( dp[j][k+j] + dp[k+j+1][j+i-1] , dp[j][j+i-1] );
                   dp[j][j+i*(ok+1)-1] =min( dp[j][j+i*(ok+1)-1],dp[j][j+i-1]*(ok+1));
                   dp[j][j+i*(ok+1)-1] =min(dp[j][j+i*(ok+1) -1 ] ,dp[j][j+i-1]+2+ccc(ok+1) );
              }
          }
          for(int i=1; i<=n; ++i){
              for(int j=0; j+i-1<n; ++j)
                 for(int k=0; k<i-1; ++k)
                   dp[j][j+i-1]=min(dp[j][j+i-1],dp[j][j+k]+dp[j+k+1][i+j-1]);
          }
          printf("%d
",dp[0][n-1]);
     }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Opaser/p/4067108.html