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
",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 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3313899.html