bzoj 1055: [HAOI2008]玩具取名(区间DP)
2018-03-13 20:44
435 查看
传送门
戳戳戳题解
貌似我就没写过几道区间DP的题,好像除了石子合并和某四边形优化果题就没了。。这题要求让连续的一段缩起来,而且长的能不能缩取决于短的缩出来的是什么。于是这就是一个区间DP了。
设dp[x][l][r]表示从l到r缩成x是否可行。我们枚举中间点k和操作就可以转移了。区间DP的k的取值一般是左闭右开的,我又回忆起来了。嗯。
代码
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <algorithm> #include <cstdlib> #define maxn 222 using namespace std; char s[5], S[maxn]; int a[maxn], b[maxn], c[maxn]; int n1, n2, n3, n4, n, len; bool dp[maxn][maxn][maxn]; int main(){ scanf("%d%d%d%d", &n1, &n2, &n3, &n4); n = n1 + n2 + n3 + n4; for(int i = 1; i <= n; i++){ scanf("%s", s); a[i] = s[0]-'A'; b[i] = s[1]-'A'; if(i <= n1) c[i] = 'W'-'A'; else if(i <= n1+n2) c[i] = 'I'-'A'; else if(i <= n1+n2+n3) c[i] = 'N'-'A'; else c[i] = 'G'-'A'; } scanf("%s", S); len = strlen(S); for(int i = 1; i <= len; i++) dp[S[i-1]-'A'][i][i] = true; for(int l = 2; l <= len; l++) for(int i = 1; i <= len-l+1; i++){ int j = i + l - 1; for(int k = i; k < j; k++) for(int p = 1; p <= n; p++) dp[c[p]][i][j] |= dp[a[p]][i][k] && dp[b[p]][k+1][j]; } bool WY = false; if(dp['W'-'A'][1][len]) putchar('W'), WY = true; if(dp['I'-'A'][1][len]) putchar('I'), WY = true; if(dp['N'-'A'][1][len]) putchar('N'), WY = true; if(dp['G'-'A'][1][len]) putchar('G'), WY = true; if(!WY) puts("The name is wrong!"); return 0; }
相关文章推荐
- bzoj 1055: [HAOI2008]玩具取名【区间dp】
- bzoj 1055 [HAOI2008]玩具取名(区间DP)
- bzoj1055 [HAOI2008]玩具取名[区间DP]
- BZOJ1055: [HAOI2008]玩具取名 区间DP
- bzoj1055[HAOI2008]玩具取名 (区间dp)
- [BZOJ1055][HAOI2008]玩具取名 区间dp
- [bzoj1055][HAOI2008]玩具取名(区间dp)
- [区间DP] bzoj1055 [HAOI2008]玩具取名
- bzoj 1055: [HAOI2008]玩具取名(区间DP)
- BZOJ1055[HAOI2008]玩具取名 【区间dp + 记忆化搜索】
- bzoj1055[HAOI2008]玩具取名 区间dp
- 【BZOJ1055】[HAOI2008]玩具取名【区间DP】【状压】
- bzoj 1055 [HAOI2008]玩具取名(区间DP)
- BZOJ1055[HAOI2008]玩具取名 【区间dp + 记忆化搜索】
- 【bzoj1055】【区间DP 记忆化搜索】[HAOI2008]玩具取名 把所给的字符串缩成WING这四个字符之一
- 【BZOJ 1055】【HAOI 2008】玩具取名 【区间DP】
- BZOJ 1055: [HAOI2008]玩具取名【区间DP】
- [bzoj1055][HAOI2008]玩具取名_区间dp
- BZOJ 1055 (HAOI 2008)玩具取名 (区间覆盖DP)
- 【BZOJ 1055】[HAOI2008]玩具取名 bool型dp