• 洛谷 4302 BZOJ 1090 SCOI2003 字符串折叠 UVA1630 Folding(输出方案版)


    【题解】

      区间DP.  设f[i][j]表示i~j的最小代价。再枚举中间点k,很容易想到转移方程为f[i][j]=min(f[i][j],f[i][k]+f[k][j]),同时如果i~k可以通过重复获得i~j,那么f[i][j]=min(f[i][j],f[i][k]+len(x)+2),这里的len(x)是指重复次数在十进制下有多少位。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define LL long long
     5 #define rg register
     6 #define N 200
     7 using namespace std;
     8 int n,m,f[N][N];
     9 char s[N];
    10 inline int read(){
    11     int k=0,f=1; char c=getchar();
    12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    14     return k*f;
    15 }
    16 inline bool check(int l,int r,int end){
    17     int l1=r-l+1,l2=end-l+1;
    18     if(l2%l1) return 0;
    19     m=l2/l1;
    20     for(rg int i=1;i<=m;i++){
    21         int st=l+(i-1)*l1;
    22         for(rg int j=0;j<l1;j++) if(s[l+j]!=s[st+j]) return 0;
    23     }
    24     return 1;
    25 }
    26 inline int qlen(int x){
    27     int cnt=0;
    28     while(x){
    29         x/=10;
    30         cnt++;
    31     }
    32     return cnt;
    33 }
    34 int main(){
    35     scanf("%s",s+1); n=strlen(s+1);
    36     for(rg int i=0;i<=n;i++)
    37         for(rg int j=i;j<=n;j++) f[i][j]=j-i+1;
    38     for(rg int l=0;l<=n;l++){
    39         for(rg int i=1;i+l-1<=n;i++){
    40             int j=i+l-1;
    41             for(rg int k=i;k<=j;k++){
    42                 f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
    43                 if(check(i,k,j)){
    44                     f[i][j]=min(f[i][j],f[i][k]+2+qlen(m));
    45 //                  printf("%d %d %d
    ",i,k,j);
    46                 }
    47             }
    48         }
    49     }
    50     printf("%d
    ",f[1][n]);
    51     return 0;
    52 }
    View Code

       输出方案的版本。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define LL long long
     5 #define rg register
     6 #define N 200
     7 using namespace std;
     8 int n,m,f[N][N],ans[N],from[N][N];
     9 char s[N];
    10 inline int read(){
    11     int k=0,f=1; char c=getchar();
    12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    14     return k*f;
    15 }
    16 inline bool check(int l,int r,int end){
    17     int l1=r-l+1,l2=end-l+1;
    18     if(l2%l1) return 0;
    19     m=l2/l1;
    20     for(rg int i=1;i<=m;i++){
    21         int st=l+(i-1)*l1;
    22         for(rg int j=0;j<l1;j++) if(s[l+j]!=s[st+j]) return 0;
    23     }
    24     return 1;
    25 }
    26 inline int qlen(int x){
    27     int cnt=0;
    28     while(x){
    29         x/=10;
    30         cnt++;
    31     }
    32     return cnt;
    33 }
    34 void out(int l,int r){
    35     if(f[l][r]==r-l+1){
    36         for(rg int i=l;i<=r;i++) printf("%c",s[i]);
    37         return;
    38     }
    39     int k=from[l][r];
    40     if(check(l,k,r)){
    41         printf("%d(",m);
    42         out(l,k);
    43         printf(")");
    44     }
    45     else{
    46         out(l,k); out(k+1,r);
    47     }
    48 }
    49 int main(){
    50     while(scanf("%s",s+1)!=EOF){
    51         n=strlen(s+1);
    52         for(rg int i=0;i<=n;i++)
    53             for(rg int j=i;j<=n;j++) f[i][j]=j-i+1;
    54         for(rg int l=0;l<=n;l++){
    55             for(rg int i=1;i+l-1<=n;i++){
    56                    int j=i+l-1;
    57                 for(rg int k=i;k<=j;k++){
    58                     if(f[i][k]+f[k+1][j]<f[i][j]){
    59                         f[i][j]=f[i][k]+f[k+1][j];
    60                         from[i][j]=k;
    61                     }
    62                     if(check(i,k,j)){
    63                         int tmp=f[i][k]+2+qlen(m);
    64                         if(tmp<f[i][j]){
    65                             f[i][j]=tmp;
    66                             from[i][j]=k;
    67                         }
    68 //                      printf("%d %d %d
    ",i,k,j);
    69                     }
    70                 }
    71             }
    72         }
    73         out(1,n);
    74         puts("");
    75     }
    76 //    printf("%d
    ",f[1][n]);
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    docker-compose写法收集
    【CodeForces】704 C. Black Widow 动态规划+模拟
    【BZOJ】2693: jzptab 莫比乌斯反演
    【BZOJ】2154: Crash的数字表格 莫比乌斯反演
    【CodeForces】915 G. Coprime Arrays 莫比乌斯反演
    【CodeForces】915 F. Imbalance Value of a Tree 并查集
    【CodeForces】915 E. Physical Education Lessons 线段树
    【CodeForces】915 D. Almost Acyclic Graph 拓扑排序找环
    【Atcoder】AGC 020 B
    【Atcoder】AGC 020 D
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9461645.html
Copyright © 2020-2023  润新知