HDU 4433 类似于状态压缩的DP
这题卡了好几个小时,纠结,后来回想一下,其实是自己模型构建能力太弱了,想清楚的话就容易多了
dp[i][j] 表示位置i,j表示i,i + 1,i + 2位置上的值,dp【i】【j】确保1-----i - 1 的位置已经一一对应,
然后转移的时候就分为上和下,上的话,注意一下,第一位上升A,第二位可以上升B(B <= A) ,第三位可以上升 C(C <= B)(应该不难理解)
下的话,同理,转移的话,自己看下代码,应该蛮好理解的
#include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<cstdio> #include<map> #include<set> #include<queue> #include<cmath> #define LL long long #define INF 1 << 25 using namespace std; const int maxn = 1025; int dp[maxn][maxn]; char s[maxn],p[maxn]; int main() { while(scanf("%s%s",s + 1,p + 1) != EOF) { int len = strlen(s + 1); s[len + 1] = s[len + 2] = s[len + 3] = p[len + 1] = p[len + 2] = p[len + 3] ='0'; s[len + 4] = p[len + 4] = 0; len += 3; for(int i = 1; i <= len ; i ++) for(int j = 0; j <= 1000; j ++) dp[i][j] = INF; int st = (s[1] - '0') * 100 + (s[2] - '0') * 10 + s[3] - '0'; dp[1][st] = 0; for(int i = 1; i <= len - 3 + 1; i ++) { for(int j = 0; j <= 999; j ++) { if(dp[i][j] == INF) continue; int hun = j / 100; int ten = (j - hun * 100) / 10; int num = j - hun * 100 - ten * 10; int q1 = s[i + 3] - '0'; int up = (p[i] -'0' + 10 - hun) % 10;//将第i 位转化成对应的数字,然后开始转移 for(int k = 0;k <= up;k ++)//可以改变第二位 for(int v = 0;v <= k;v ++)//改变第三位 { int newj = 100 * (ten + k > 9 ? ten + k - 10:ten + k) + 10 * (num + v > 9 ? num + v - 10:num + v) + q1; dp[i + 1][newj] = min(dp[i + 1][newj],dp[i][j] + up); } int down = 10 - up; for(int k = 0;k <= down;k ++) for(int v = 0;v <= k;v ++) { int newj = 100 * (ten - k < 0 ? ten - k + 10:ten - k) + 10 * (num - v < 0 ? num - v + 10:num - v) + q1; dp[i + 1][newj] = min(dp[i + 1][newj],dp[i][j] + down); } } } int m = (p[len - 2] - '0')* 100 + (p[len - 1] - '0') * 10 + p[len] - '0'; printf("%d\n",dp[len - 3 + 1][m]); } return 0; }