poj3373Changing Digits(dp)
dfs倒着搜 返回的路径不能满足相同的数最多 借鉴了下别人的代码。。
先dp出来 再倒着标记一下 然后正回来一定可以满足了
dp保存的是最小的不相同数
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stdlib.h> 5 #include<algorithm> 6 using namespace std; 7 #define INF 0xfffffff 8 int dp[1010][10010]; 9 char s[1010]; 10 int flag,path[1010],k,m,pp[1010],f[1010][10100]; 11 int main() 12 { 13 int i,j,g; 14 while(scanf("%s%d",s,&m)!=EOF) 15 { 16 k = strlen(s);flag=0; 17 memset(f,0,sizeof(f)); 18 for(i = 1 ; i <= k ; i++) 19 for(j = 0 ; j <= m ; j++) 20 dp[i][j] = INF; 21 if(k==1) 22 { 23 printf("%c\n",s[0]); 24 continue; 25 } 26 for(i = 1 ; i <= 9 ; i++) 27 { 28 if(i==s[0]-'0') 29 dp[1][i%m] = min(dp[1][i%m],0); 30 else 31 dp[1][i%m] = min(dp[1][i%m],1); 32 } 33 for(i = 1 ; i < k ; i++) 34 for(j = 0 ; j<m ; j++) 35 { 36 if(dp[i][j] == INF) continue; 37 for(g = 0 ; g <= 9 ; g++) 38 { 39 int o; 40 if(g==s[i]-'0') 41 o = 0; 42 else 43 o = 1; 44 dp[i+1][(j*10+g)%m] = min(dp[i+1][(j*10+g)%m],dp[i][j]+o); 45 } 46 } 47 f[k][0] = 1; 48 for(i = k-1 ; i>=1 ; i--) 49 for(j = 0 ; j < m ; j++) 50 { 51 if(dp[i][j]==INF) continue; 52 for(g = 0 ; g <= 9 ; g++) 53 { 54 int o; 55 if(g==s[i]-'0') 56 o = 0; 57 else 58 o = 1; 59 if(dp[i][j]+o==dp[i+1][(j*10+g)%m]&&f[i+1][(j*10+g)%m]) 60 { 61 f[i][j] = 1; 62 } 63 } 64 } 65 int ss; 66 for(i = 1; i < 10 ; i++) 67 { 68 int o; 69 if(i==s[0]-'0') 70 o = 0; 71 else 72 o = 1; 73 if(f[1][i%m]&&dp[1][i%m]==o) 74 { 75 printf("%d",i); 76 ss = i%m; 77 break; 78 } 79 } 80 for(i = 2; i <= k ;i++) 81 { 82 for(g = 0 ; g <= 9 ; g++) 83 { 84 int o; 85 if(g==s[i-1]-'0') 86 o = 0; 87 else 88 o = 1; 89 if(f[i][(ss*10+g)%m]&&dp[i][(ss*10+g)%m]==dp[i-1][ss]+o) 90 { 91 printf("%d",g); 92 ss = (ss*10+g)%m; 93 break; 94 } 95 } 96 } 97 puts(""); 98 } 99 return 0; 100 }