UVALive - 2031 Dance Dance Revolution 三维dp
2015-07-12 18:21
302 查看
题目大意:有一个胖子在玩跳舞机,刚开始的位置在(0,0),跳舞机有四个方向键,上左下右分别对应1,2,3,4.现在有以下规则
1.如果从0位置移动到任意四个位置,消耗能量2
2.如果从非0位置跳到相邻的位置,如1跳到2或4,消耗能量3
3.如果从非0位置跳到对面的位置,如2跳到4,消耗能量4
4.如果跳同一个位置,消耗能量1
5.两只脚不能在同一个位置
解题思路:这题其实很水,直接暴力就可以解决了,讨论所有情况,用dp[i][j][k]表示跳第k个数字,左脚在i这个位置,右脚在j这个位置时所消耗的能量,接着分类讨论
1.如果其中一只脚在0上的情况
2.其中一只脚踩的数字和当前要跳的数字一样
3.两只脚踩的数字和当前的数字不一样
三种情况,分别在细分即可,具体看代码
1.如果从0位置移动到任意四个位置,消耗能量2
2.如果从非0位置跳到相邻的位置,如1跳到2或4,消耗能量3
3.如果从非0位置跳到对面的位置,如2跳到4,消耗能量4
4.如果跳同一个位置,消耗能量1
5.两只脚不能在同一个位置
解题思路:这题其实很水,直接暴力就可以解决了,讨论所有情况,用dp[i][j][k]表示跳第k个数字,左脚在i这个位置,右脚在j这个位置时所消耗的能量,接着分类讨论
1.如果其中一只脚在0上的情况
2.其中一只脚踩的数字和当前要跳的数字一样
3.两只脚踩的数字和当前的数字不一样
三种情况,分别在细分即可,具体看代码
[code]#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define maxn 50010 #define INF 0x3f3f3f3f int dp[5][5][maxn]; int seq[maxn]; int strength[2] = {4,3}; int n; int solve() { memset(dp, 0x3f, sizeof(dp)); dp[0][seq[0]][0] = dp[seq[0]][0][0] = 2; for(int i = 1; i < n; i++) { for(int j = 0; j < 5; j++) { if(dp[j][seq[i-1]][i-1] != INF) { if(j == 0) { if(seq[i] != seq[i-1]) dp[seq[i]][seq[i-1]][i] = dp[j][seq[i-1]][i-1] + 2; if(seq[i] == seq[i-1]) dp[j][seq[i-1]][i] = dp[j][seq[i-1]][i-1] + 1; else dp[j][seq[i]][i] = dp[j][seq[i-1]][i-1] + strength[(seq[i-1] + seq[i]) % 2]; } else if(j == seq[i] || seq[i-1] == seq[i]) dp[j][seq[i-1]][i] = min(dp[j][seq[i-1]][i],dp[j][seq[i-1]][i-1] + 1); else { dp[seq[i]][seq[i-1]][i] = min(dp[j][seq[i-1]][i-1] + strength[(j + seq[i]) % 2], dp[seq[i]][seq[i-1]][i]); dp[j][seq[i]][i] = min(dp[j][seq[i-1]][i-1] + strength[(seq[i-1] + seq[i] ) % 2], dp[j][seq[i]][i]); } } if(dp[seq[i-1]][j][i-1] != INF) { if(j == 0) { if(seq[i] != seq[i-1]) dp[seq[i]][seq[i-1]][i] = dp[seq[i-1]][j][i-1] + 2; if(seq[i] == seq[i-1]) dp[seq[i-1]][j][i] = dp[seq[i-1]][j][i-1] + 1; else dp[seq[i]][j][i] = dp[seq[i-1]][j][i-1] + strength[(seq[i-1] + seq[i]) % 2]; } if(j == seq[i] || seq[i-1] == seq[i]) dp[seq[i-1]][j][i] = min(dp[seq[i-1]][j][i],dp[seq[i-1]][j][i-1] + 1); else { dp[seq[i]][seq[i-1]][i] = min(dp[seq[i-1]][j][i-1] + strength[(j + seq[i]) % 2], dp[seq[i]][seq[i-1]][i]); dp[seq[i]][j][i] = min(dp[seq[i-1]][j][i-1] + strength[(seq[i-1] + seq[i] ) % 2], dp[seq[i]][j][i]); } } } } int ans = INF; for(int i = 0; i < 5; i++) ans = min(min(ans, dp[seq[n-1]][i][n-1]), dp[i][seq[n-1]][n-1]); return ans; } int main() { n = 0; while(scanf("%d", &seq ) != EOF && seq[n++]) { while(scanf("%d", &seq ) && seq ) n++; printf("%d\n", solve()); n = 0; } return 0; }
相关文章推荐
- 2015年7月11日-FW
- 让Android虚拟手机快速启动
- int和long int为什么字节数是一样的?
- 一种排序
- 交换排序之快速排序
- 关于值栈
- About Django
- 建站笔记2-数据库密码修改和phpmyadmin的使用
- iBatis简单入门教程
- 喷水装置(一)
- html5标签及语义化
- MATLAB 复制文件
- ZOJ3629 Treasure Hunt IV(找到规律,按公式)
- uva 10483(暴力)
- 横竖屏切换时,禁止activity重新创建,android:configChanges="keyboardHidden|orientation" 不起作用
- Linux命令之find(二)
- Linux高级文件系统管理之磁盘阵列简介
- 自定义表单样式之checkbox和radio
- 用实例详细讲解将PSD转成HTML&CSS
- jQuery -> bind / live / delegate 终结者 - on