codeforces137d

Posted pandaking

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces137d相关的知识,希望对你有一定的参考价值。

题意如下:给你一串字符串,然后再给你一个数字n,要你把这个字符串分成s个回文串,s为小于等于n中的任意数字,然后接下来要你求分成s个回文串的最小改变字符数!

这道题很明显是要先预处理一下,然后记录路径,最后再输出,输出方案方案的话是记录路径。

1:我感觉我还是没有想清楚就开始写了。

2:我又忘记了如果变量不开全局要初始化这件大事。

接下来是代码:

技术分享图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <string>
 7 using namespace std;
 8 int dp[700][700],g[700][700],c[700][700];
 9 char sz[700];
10 int n,len;
11 /*
12 void print(int k,int nows){
13     if(!k) return;
14     print(g[k][nows],nows-1);
15     if(g[k][nows]) printf("+");
16     for(int i=1;i<=k-g[k][nows];i++)
17         putchar(sz[min(g[k][nows]+i,k-i+1)]);
18 
19 }
20 */
21 
22 void print(int n,int r) {
23     if(!n)    return;
24     print(g[n][r],r-1);
25     if(g[n][r])    putchar(+);
26     for(int i=1;i<=n-g[n][r];i++)
27         putchar(sz[min(g[n][r]+i,n-i+1)]);
28 }
29 
30 int main(){
31     scanf("%s",sz+1);
32     len=strlen(sz+1);
33     scanf("%d",&n);
34     for(int i=1;i<=len;i++){
35         for(int j=i;j<=len;j++){
36             for(int l=i,r=j;l<r;l++,r--){
37                 if(sz[l]!=sz[r]) c[i][j]++;
38             }
39         }
40     }
41     memset(dp,0x3f,sizeof(dp));dp[0][0]=0;
42     for(int i=1;i<=len;i++){
43         for(int j=1;j<=n;j++){
44             for(int k=0;k<i;k++){
45                 if(dp[i][j]>dp[k][j-1]+c[k+1][i]){
46                     dp[i][j]=dp[k][j-1]+c[k+1][i];
47                     g[i][j]=k;
48                 }
49             }
50         }
51     }
52     int ans=0x3f,tip=1;
53     for(int i=1;i<=n;i++){
54         if(dp[len][tip]>dp[len][i]){
55             tip=i;
56         }
57     }
58     printf("%d
",dp[len][tip]);
59     print(len,tip);
60     printf("
");
61     return 0;
62 }
View Code

 我的新写的代码,带注释

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 char sz[550];
 7 int dp[550][550],g[550][550],c[550][550];
 8 int len,n,r=0;//首先如果不是一定要开局部变量,那么就开全局变量
 9 
10 void print(int a,int b){
11     if(b==0) return;//确定边界
12     print(g[a][b],b-1);
13     if(b>1) putchar(+);//要注意好输出这个的顺序
14     //printf("%d %d
",);
15     for(int i=g[a][b]+1,s=0;i<=a;i++,s++){ //我一直卡在了怎么确定起点和终点   其实不难,但是要多小心
16         printf("%c",sz[min(i,a-s)]);//取他们的最小值
17     }
18 }
19 
20 int main(){
21     scanf("%s",sz+1);
22     len=strlen(sz+1);
23     scanf("%d",&n);
24     for(int i = 1;i<=len;++i){//以后遇到这种东西首先要想到预处理好
25         for(int j=i;j<=len;++j){
26              for(int l=i,r=j;l<r;l++,r--){
27                  if(sz[l]!=sz[r]) c[i][j]++;
28              }
29         }
30     }
31     memset(dp,0x3f,sizeof(dp));dp[0][0]=0;//初始化
32     for(int i=1;i<=len;i++){
33         for(int j=1;j<=n;j++){
34             for(int k=0;k<i;k++){
35                 if(dp[i][j]>dp[k][j-1]+c[k+1][i]){
36                     dp[i][j]=dp[k][j-1]+c[k+1][i];
37                     g[i][j]=k;//记录路径
38                 }
39             }
40         }
41     }
42     for(int i=1;i<=n;i++){
43         if(dp[len][r]>dp[len][i]){
44             r=i;//不要开局部变量 ,否则会gg
45         }
46     }
47     printf("%d
",dp[len][r]);
48     //printf("%d  %d
",r,g[len][r]);
49     print(len,r);
50     printf("
");
51     return 0;
52 }
View Code

 

以上是关于codeforces137d的主要内容,如果未能解决你的问题,请参考以下文章

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段

c_cpp Codeforces片段

Codeforces 86C Genetic engineering(AC自动机+DP)

CodeForces 1005D Polycarp and Div 3(思维贪心dp)

(Incomplete) Codeforces 394 (Div 2 only)

CodeForces 931F Teodor is not a liar!