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 }
我的新写的代码,带注释
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 }
以上是关于codeforces137d的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段
Codeforces 86C Genetic engineering(AC自动机+DP)
CodeForces 1005D Polycarp and Div 3(思维贪心dp)