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 }
View Code

 

你可能感兴趣的:(git)