☆UVALive 7276 Wooden Signs (DP or 记忆化搜索)
2017-03-31 13:31
465 查看
题意:摆木图, 一共n层木头,告诉你第一个木头尾端跟头端的位置,其余n-1层头端的位置,组合方法是,上面图的方法。。。要么尾端跟尾端一起,要么尾端跟头端一起(必须有一定长度的木头支撑,具体看图)
思路:这题一开拿到只知道怎么转移。。3种情况(可以化简为2种),但不知道怎么写啊。。。这木头咋状态表示啊。。后来发现自己真的zz, 一共两头。。而且每个首部都告诉你了,你直接记录尾部的位置就好了啊。。。那样下面木头就固定了,就可以转移了啊。。。真的zz。。dp[i]【j】 表示第i个木头,他的尾部的位置为j,这样他的头部a[i]跟尾部就确定了,那么对于第i个木头,他肯定是从i-1木头转移过来的,确定i-1木头的左右区间,然后就三种转移:一种是i+1的头部在第i根整段的左边,一种是在右边,还有在中间,中间的有两种情况,其他都只有一种
递推代码:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int Mod = 2147483647; const int maxn = 2e3 + 5; ll dp[maxn][maxn]; int a[maxn]; int main() { int n; while(~scanf("%d", &n)) { memset(dp, 0, sizeof(dp)); for(int i = 0; i <= n; i++) scanf("%d", &a[i]); dp[1][a[0]] = 1; for(int i = 2; i <= n; i++) { for(int j = 1; j <= n+1; j++) { int l = min(a[i-1], j), r = max(a[i-1], j); if(a[i] <= l) //三种转移 { dp[i][r] += dp[i-1][j]; dp[i][r] %= Mod; } else if(a[i] >= r) { dp[i][l] += dp[i-1][j]; dp[i][l] %= Mod; } else { dp[i][l] += dp[i-1][j]; dp[i][r] += dp[i-1][j]; dp[i][l] %= Mod; dp[i][r] %= Mod; } } } ll ans = 0; for(int i = 1; i <= n+1; i++) { ans += dp [i]; ans %= Mod; } printf("%lld\n", ans); } return 0; }
记忆化代码(把递推的分类简化了一下):
记忆化就不比每种状态都遍历了,从最开始王下遍历,cur代表现在的层数i,ppos代表上一个木头尾部在哪里。。因为转移根据上一个来的
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> using namespace std; typedef long long ll; const int Mod = 2147483647; const int maxn = 2e3 + 5; ll dp[maxn][maxn]; int a[maxn]; int n; ll dfs(int cur, int ppos) { if(cur > n) return 1; if(dp[cur][ppos]) return dp[cur][ppos]; int l = min(a[cur-1], ppos), r = max(a[cur-1], ppos); if(a[cur] < r) dp[cur][ppos] = (dp[cur][ppos] + dfs(cur+1, r))%Mod; if(a[cur] > l) dp[cur][ppos] = (dp[cur][ppos] + dfs(cur+1, l))%Mod; return dp[cur][ppos]; } int main() { while(~scanf("%d", &n)) { for(int i = 0; i <= n; i++) scanf("%d", &a[i]); memset(dp, 0, sizeof(dp)); ll ans = dfs(2, a[0]); printf("%lld\n", ans); } return 0; }
相关文章推荐
- UVALive 7276 Wooden Signs
- UVALive 7276 Wooden Signs (DP)
- Wooden Signs uvalive gym 区间dp
- UVALive 6432 —— Influence(记忆化搜索 + 状态压缩)
- 100道动态规划——30 UVAlive 3907 Puzzle AC自动机上的动态规划,记忆化搜索
- UVALive 6432 In uence(枚举+dfs或记忆化搜索+bitset)
- UVALive 3710 Interconnect(记忆化搜索 + hash)
- 【区间dp】【记忆化搜索】UVALive - 3516 - Exploring Pyramids
- uvalive 2322 Wooden Sticks(贪心)
- uva live-2322 - Wooden Sticks
- UVALive 4844 String Popping【记忆化搜索】
- UVALive - 6469(博弈、记忆化搜索)
- UVAlive 2322 Wooden Sticks(贪心)
- UVALive 2322 Wooden Sticks 截木棍 排序+贪心
- UVALive 4864 Bit Counting --记忆化搜索 / 数位DP?
- UVALive 6850 Hidden Plus Signs(dfs)
- UVALIVE 2322 Wooden Sticks
- UVAlive 2322 Wooden Sticks(贪心)
- uvalive 2322 Wooden Sticks(贪心)
- UVALive 4050 Hanoi Towers(记忆化搜索)