一道不错的dp题
来源:互联网 发布:淘宝入住条件与费用 编辑:程序博客网 时间:2024/05/21 09:33
http://codeforces.com/contest/18/problem/E
状态很容易设计,但如果直接求解的话复杂度很高,需要技巧优化决策步骤。
#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <map>using namespace std;typedef long long LL;typedef unsigned long long ULL;const int MAXN(50010);template<typename T>bool checkmin(T &a, const T &b){ return b < a? (a = b, true): false;}template<typename T>bool checkmax(T &a, const T &b){ return b > a? (a = b, true): false;}inline int lowb(int i){return i&-i;}int gcd(int a, int b){ while(b){ int t = a%b; a = b; b = t; } return a;}struct AR{ int v, s; friend bool operator <(const AR &a, const AR &b){ return a.v == b.v? a.s < b.s: a.v < b.v; }}ar[651];bool co[651][651]; //co[i][j]表示编号为i的决策是否与编号为j的决策冲突,i与j为相邻两行决策int op[651][2], mp[26][26], pre[501][651], dp[501][651];char ma[501][501];int main(){ int cnt = 0; for(int i = 0; i < 26; ++i) for(int j = 0; j < 26; ++j) if(i != j){ mp[i][j] = ++cnt; op[cnt][0] = i; op[cnt][1] = j; } for(int i = 0; i < 26; ++i) for(int j = 0; j < 26; ++j) if(i != j){ for(int k = 0; k < 26; ++k){ if(i != k) co[mp[i][j]][mp[i][k]] = true; if(j != k) co[mp[i][j]][mp[k][j]] = true; } } int n, m; scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) scanf("%s", ma[i]); for(int i = 1; i <= n; ++i){ int tn = 0; for(int j = (i == 1? 0: 1); j <= cnt; ++j){ ar[tn].v = dp[i-1][j]; ar[tn++].s = j; } sort(ar, ar+tn); for(int j = 1; j <= cnt; ++j) dp[i][j] = m; for(int j = 0; j < m; ++j){ //利用小字符集优化转移费用计算 int t = ma[i][j]-'a'; for(int k = 0; k < 26; ++k) if(t != k){ if(j&1) --dp[i][mp[k][t]]; else --dp[i][mp[t][k]]; } } for(int j = 1; j <= cnt; ++j) for(int k = 0; k < tn; ++k) //可以证明k<=50时一定会break if(!co[j][ar[k].s]){ dp[i][j] += ar[k].v; pre[i][j] = ar[k].s; break; } } int ans = n*m+1, ts; for(int i = 1; i <= cnt; ++i) if(checkmin(ans, dp[n][i])) ts = i; for(int i = n; i >= 1; --i){ for(int j = 0; j < m; ++j) ma[i][j] = op[ts][j&1]+'a'; ts = pre[i][ts]; } printf("%d\n", ans); for(int i = 1; i <= n; ++i) printf("%s\n", ma[i]); return 0;}
0 0
- 一道不错的dp题
- poj3345Bribing FIPA(树形DP,一道不错的题)
- USACO Section 3.4 Raucous Rockers - 一道不错的DP
- 一道不错的题(换位考虑)
- 一道典型的DP题
- 一道不错的面试题
- 又一道挺不错的深度优先搜索题
- 百度知道里面的一道题,不错(Java GC)
- POJ 2501 Average Speed(不错的一道水题)
- poj 1080 一道经典的dp题
- 论一道水题dp的优化。。。。
- 一道非常好的DP,菜狗子多做这种题
- 一道神奇的树形dp题
- 一道DP的思考题
- 一道不错的c语言面试题
- 一道关于DP的ACM
- 一道画风清奇的数位dp
- HDU 4055 Number String(不错的DP题)
- MFC对话框-重绘非客户端区域(标题栏)
- Android系列---JSON数据解析
- 谷歌浏览器Chrome播放rtsp视频流解决方案
- The hierarchy of the type RotateLoadingLayout is inconsistent
- No implementation found for native Lorg/opencv/core/Mat;.n_Mat ()J
- 一道不错的dp题
- Jquery确定鼠标进入div的方向
- 图解Android - Binder 和 Service
- 7、oracle vm virtualbox & ubuntu-14.04 应用环境配置方法总结
- 在注册广播的时候就更新一次数据的一种方式:电量计控件BatteryMeterView
- What really happens when you navigate to a URL--网页url跳转过程
- oracle 取左表不在右表记录的3种方法-引申到db2-开发系列(五)
- ping过程详解
- android 动态库死机调试方法