uva 10618 Tango Tango Insurrection 动态规划
2015-09-16 17:51
393 查看
// uva 10618 Tango Tango Insurrection 动态规划 // // 解题思路: // // 这是看的条件最多的一个动态规划了.看了很久很久,虽然 // 状态很好理解,但是限制特别多. // d[i][a][b][s]表示到达第i个指示灯的时候,左脚在a,右脚 // 在b,上一次移动的脚为s(没有移动0,左脚1,右脚2)所需的最小花 // 费.并将四个方向分别编号为上0,下3,左1,右2.这样编码的方式 // 对于求相对的方向只要和为3即可. // 状态转移如下: // 如果当前是'.'.可以选择不动,左脚移到其他方向,或者 // 右脚移动到其他方向. // 如果当前是某一个方向,则左脚移动到该位置上,右脚移 // 动到该位置上. // 采用逆推的方法. // // 详细的细节请看程序.大神的code十分的优雅,而且十分的巧妙,在 // 这里向刘老师致敬~~~~ #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int LEFT = 1; const int RIGHT = 2; const int MAXN = 108; int n; int d[MAXN][4][4][3]; char seq[MAXN]; int action[MAXN][4][4][3]; // 将移动哪只脚以及方向变成一个整数存进数组 char place[] = ".LR"; int pos[256]; int energy(int a,int ta){ if (a == ta) return 3; // 相同的位置 if (a + ta == 3) return 7; // 相对的位置 return 5; // 相邻的位置 } int energy(int a,int b,int s,int f,int t,int &ta,int &tb){ ta = a; tb = b; if (f == 1) ta = t; else if (f == 2) tb = t; if (ta == tb) return -1; // 下一个状态猜到同一个位置 if (ta == RIGHT && tb == LEFT) return -1; // 背向跳舞机 if (a == RIGHT && tb != b) return -1; // a左脚在右脚的位置,但是移动了右脚,无论移动到哪儿,都是不合法的 if (b == LEFT && ta != a) return -1; // b右脚在左脚的位置,但是移动了右脚,无论一定到哪儿,都是不合法的 int e = 0; if (f == 0) // 没有脚移动 e = 0; else if (f != s) //上一次移动的脚不是现在移动的脚 e = 1; else { if (f == 1) // 移动的是左脚, e = energy(a,ta); else // 移动的是右脚 e = energy(b,tb); } return e; } void update(int i,int a,int b,int s,int f,int t){ int ta,tb; int e; e = energy(a,b,s,f,t,ta,tb); if (e < 0) return ; int cost = d[i+1][ta][tb][f] + e; int &ans = d[i][a][b][s]; if (ans > cost){ ans = cost; action[i][a][b][s] = f * 4 + t; } } void solve(){ n = strlen(seq); memset(d,0,sizeof(d)); for (int i = n-1;i >=0 ;i --){ for (int a = 0; a < 4 ;a ++ ){ for (int b = 0; b < 4; b ++){ if (a == b) continue; for (int s = 0; s < 3; s++){ d[i][a][b][s] = 0x1f1f1f1f; if (seq[i] == '.'){ update(i,a,b,s,0,0); for (int t = 0 ; t < 4; t++){ update(i,a,b,s,1,t); update(i,a,b,s,2,t); } }else { update(i,a,b,s,1,pos[seq[i]]); update(i,a,b,s,2,pos[seq[i]]); } } } } } int a = 1; int b = 2; int s = 0; for (int i = 0 ;i < n ; i++){ int f = action[i][a][b][s] / 4; int t = action[i][a][b][s] % 4; printf("%c",place[f]); s = f; if (f == 1) a = t; else if (f == 2){ b = t; } } puts(""); //printf("%d\n",d[0][1][2][0]); } int main(){ pos['U'] = 0; pos['D'] = 3; pos['L'] = 1; pos['R'] = 2; //freopen("1.txt","r",stdin); while(scanf("%s",seq)!=EOF){ if (seq[0] == '#') break; solve(); } return 0; }
相关文章推荐
- Django模板系统
- Algorithms—239.Sliding Window Maximum
- poj2417 Baby-StepGiant-StepAlgorithm a^x=b%P
- 【hihoCoder】#1086: Browser Caching (微软笔试题)
- Algorithms—87.Scramble String
- django 1.8 官方文档翻译:7-3 Django管理文档生成器
- 电脑技巧---完全控制面板---上帝模式(God Mode)
- django 1.8 官方文档翻译:8-5 加密签名
- Google Gson 使用简介
- 【英语】Bingo口语笔记(86) - stand系列
- django 1.8 官方文档翻译:13-3 日志
- 博客园刷星golang v0.1
- ubuntu14.04 安装google chrome
- Django框架如何使用ajax的post方法
- mac下安装go
- emoji 表情过滤 解决 sogo 输入法输入表情 服务器不支持
- google bigtable论文,其引用的文献都应该很经典
- Algorithms - Week 4-1 Elementary Symbol Tables
- Best Compression Algorithms(网易游戏2015笔试题)
- POJ1389Area of Simple Polygons【离散化+线段树+扫描线】