区间dp
dp[i][j]存i->j区间的所有取值
然后枚举分割点,枚举两个存的值,分别运算存储。
看见这种不确定分割顺序,两个区间合并的情况,就要用区间dp。
#include<bits/stdc++.h> using namespace std; const int N = 60; int n, kase; int vis[N * 110]; char s[N]; vector<int> dp[N][N]; int main() { while(scanf("%s", s + 1)) { if(s[1] == ‘0‘) break; n = strlen(s + 1); for(int i = 1; i <= n; ++i) for(int j = i; j <= n; ++j) dp[i][j].clear(); for(int i = 1; i <= n; ++i) { if(s[i] == ‘I‘) dp[i][i].push_back(1); if(s[i] == ‘V‘) dp[i][i].push_back(5); if(s[i] == ‘X‘) dp[i][i].push_back(10); if(s[i] == ‘L‘) dp[i][i].push_back(50); if(s[i] == ‘C‘) dp[i][i].push_back(100); } for(int len = 1; len <= n; ++len) for(int i = 1; i <= n - len + 1; ++i) { for(int j = i; j < i + len; ++j) for(int x = 0; x < dp[i][j].size(); ++x) for(int y = 0; y < dp[j + 1][i + len - 1].size(); ++y) if(dp[i][j][x] < dp[j + 1][i + len - 1][y] && !vis[dp[j + 1][i + len - 1][y] - dp[i][j][x]]) { dp[i][i + len - 1].push_back(dp[j + 1][i + len - 1][y] - dp[i][j][x]); vis[dp[j + 1][i + len - 1][y] - dp[i][j][x]] = 1; } else if(dp[i][j][x] >= dp[j + 1][i + len - 1][y] && !vis[dp[j + 1][i + len - 1][y] + dp[i][j][x]]) { vis[dp[j + 1][i + len - 1][y] + dp[i][j][x]] = 1; dp[i][i + len - 1].push_back(dp[j + 1][i + len - 1][y] + dp[i][j][x]); } for(int x = 0; x < dp[i][i + len - 1].size(); ++x) vis[dp[i][i + len - 1][x]] = 0; } sort(dp[1][n].begin(), dp[1][n].end()); printf("Case %d:", ++kase); for(int i = 0; i < dp[1][n].size(); ++i) printf(" %d", dp[1][n][i]); puts(""); } return 0; }
时间: 2024-12-13 16:55:31