HDU 3565 Bi-peak Number(数位DP)题解
题意:我们定义每一位先严格递增(第一位不为0)后严格递减的数为峰(比如1231),一个数由两个峰组成称为双峰,一个双峰的价值为每一位位数和,问L~R双峰最大价值
思路:数位DP。显然这个问题和pos有关,和前一项有关,和当前状态有关,我们定义dp[i][j][k]第i位前面j状态k的后面的最佳情况。
状态有7种:
0什么都没,1刚开始第一个上坡,2已经第一个上坡了可以转折了,3第一个下坡0
4刚开始第二个上坡,5已经第二个上坡可以转折了,6第二个下坡
然后数位DP一下就好了。
注意,要开ull,30多个wa的教训
代码:
#include<set> #include<map> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 10000 + 10; const ull seed = 131; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int dp[30][10][10]; //0什么都没,1刚开始第一个上坡,2已经第一个上坡了,3第一个下坡0 //4刚开始第二个上坡,5已经第二个上坡,6第二个下坡 //第i位前面j状态k的后面的最佳情况 int top[30], low[30]; int dfs(int pos, int pre, int st, bool MAXflag, bool MINflag){ if(pos == -1) return st == 6? 0 : -INF; if(!MINflag && !MAXflag && dp[pos][pre][st] != -1) return dp[pos][pre][st]; int Min = MINflag? low[pos] : 0; int Max = MAXflag? top[pos] : 9; int ans = -INF; for(int i = Min; i <= Max; i++){ int newSt; if(st == 0){ if(i == 0) newSt = 0; else newSt = 1; } else if(st == 1){ if(i <= pre) continue; if(i > pre) newSt = 2; } else if(st == 2){ if(i == pre) continue; if(i < pre) newSt = 3; else newSt = 2; } else if(st == 3){ if(i < pre) newSt = 3; else if(i > pre) newSt = 4; else{ if(i) newSt = 4; else continue; } } else if(st == 4){ if(i <= pre) continue; newSt = 5; } else if(st == 5){ if(i == pre) continue; if(i > pre) newSt = 5; else newSt = 6; } else if(st == 6){ if(i >= pre) continue; newSt = 6; } ans = max(ans, i + dfs(pos - 1, i, newSt, MAXflag && i == Max, MINflag && i == Min)); } if(!MAXflag && !MINflag) dp[pos][pre][st] = ans; return ans; } int solve(ull l, ull r){ int pos = 0; while(r){ top[pos] = r % 10; low[pos++] = l % 10; r /= 10; l /= 10; } int ans = dfs(pos - 1, 0, 0, true, true); return max(0, ans); } int main(){ int t, ca = 1; memset(dp, -1, sizeof(dp)); scanf("%d", &t); while(t--){ ull l, r; cin >> l >> r; printf("Case %d: %d\n", ca++, solve(l, r)); } return 0; }