DP——Hard problem (Codeforces Round #367 (Div. 2) C)
2016-09-09 17:15
375 查看
题目链接:
http://codeforces.com/contest/706/problem/C
分析:
给出n个字符串和把每个字符串翻转所需要的费用Ci,每个字符串都可以选择翻转或者不翻转,求将n个字符串变成字典序所需要的最小费用,若不能变成字典序则输出-1.
字典序: 若在字典序上A在B前面则A是B的前缀 或者 A和B第一个不相同的字符是A[i]<B[i]。
题解:
设dp[i][1]/[0] 表示第i个字符串翻转/不翻转时构成字典序的最小cost。
初始化: dp[1][0] = 0, dp[1][1] = cost[1];
(str[i]表示第i个字符串, ~str[i]表示第i个字符串翻转)
第一个判断:
str[i] > str[i-1] && str[i]> ~str[i-1] dp[i][0] = min(dp[i][0], min(dp[i-1][0], dp[i-1][1]) );
str[i] > str[i-1] && str[i]< ~str[i-1] dp[i][0] = min(dp[i][0], dp[i-1][0]);
str[i] < str[i-1] && str[i]> ~str[i-1] dp[i][0] = min(dp[i][0], dp[i-1][1]);
str[i] < str[i-1] && str[i]< ~str[i-1] dp]i][0] = INF;
第二个判断:
~str[i] > str[i-1] && str[i]> ~str[i-1] dp[i][1] = min(dp[i][1], min(dp[i-1][0], dp[i-1][1])+cost[i] );
~str[i] > str[i-1] && str[i]< ~str[i-1] dp[i][1] = min(dp[i][1], dp[i-1][0]+cost[i] );
~str[i] < str[i-1] && str[i]> ~str[i-1] dp[i][1] = min(dp[i][1], dp[i-1][1]+cost[i] );
~str[i] < str[i-1] && str[i]< ~str[i-1] dp]i][1] = INF;
AC代码:
http://codeforces.com/contest/706/problem/C
分析:
给出n个字符串和把每个字符串翻转所需要的费用Ci,每个字符串都可以选择翻转或者不翻转,求将n个字符串变成字典序所需要的最小费用,若不能变成字典序则输出-1.
字典序: 若在字典序上A在B前面则A是B的前缀 或者 A和B第一个不相同的字符是A[i]<B[i]。
题解:
设dp[i][1]/[0] 表示第i个字符串翻转/不翻转时构成字典序的最小cost。
初始化: dp[1][0] = 0, dp[1][1] = cost[1];
(str[i]表示第i个字符串, ~str[i]表示第i个字符串翻转)
第一个判断:
str[i] > str[i-1] && str[i]> ~str[i-1] dp[i][0] = min(dp[i][0], min(dp[i-1][0], dp[i-1][1]) );
str[i] > str[i-1] && str[i]< ~str[i-1] dp[i][0] = min(dp[i][0], dp[i-1][0]);
str[i] < str[i-1] && str[i]> ~str[i-1] dp[i][0] = min(dp[i][0], dp[i-1][1]);
str[i] < str[i-1] && str[i]< ~str[i-1] dp]i][0] = INF;
第二个判断:
~str[i] > str[i-1] && str[i]> ~str[i-1] dp[i][1] = min(dp[i][1], min(dp[i-1][0], dp[i-1][1])+cost[i] );
~str[i] > str[i-1] && str[i]< ~str[i-1] dp[i][1] = min(dp[i][1], dp[i-1][0]+cost[i] );
~str[i] < str[i-1] && str[i]> ~str[i-1] dp[i][1] = min(dp[i][1], dp[i-1][1]+cost[i] );
~str[i] < str[i-1] && str[i]< ~str[i-1] dp]i][1] = INF;
AC代码:
/************************************************************************* > File Name: test.cpp > Author: Akira > Mail: qaq.febr2.qaq@gmail.com ************************************************************************/ #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <cmath> #include <vector> #include <set> #include <list> #include <ctime> typedef long long LL; typedef unsigned long long ULL; typedef long double LD; #define MST(a,b) memset(a,b,sizeof(a)) #define CLR(a) MST(a,0) #define Sqr(a) ((a)*(a)) using namespace std; #define MaxN 100005 #define MaxM MaxN*10 #define INF (LL)1e15 #define bug cout<<88888888<<endl; int n; LL cost[MaxN]; string str[MaxN]; string Rstr[MaxN]; LL dp[MaxN][2]; string Re(string str) { string s; for(int i=str.length()-1;i>=0;i--) { s+=str[i]; } return s; } bool judge(string a, string b) { if(a==b) return true; int alen = a.length(); int blen = b.length(); if(alen > blen) { int i=0; while(a[i]==b[i] && i<blen) i++; if(i>=blen) return true; if( a[i]>b[i] ) return true; else return false; } else { int i=0; while(a[i]==b[i] && i<alen) i++; if(i>=alen) return false; if( a[i]>b[i] ) return true; else return false; } } void solve() { for(int i=1;i<=n;i++) { Rstr[i] = Re(str[i]); //cout << Rstr[i] << endl; } for(int i=1;i<=n;i++) { dp[i][0]=INF; dp[i][1]=INF; //cout << dp[i][1] << endl; } dp[1][0] = 0; dp[1][1] = cost[1]; for(int i=2;i<=n;i++) { int flag0 = judge(str[i], str[i-1]); int flag1 = judge(str[i], Rstr[i-1]); //cout << flag0 << " " << flag1 << endl; if( flag0 && flag1 ) dp[i][0] = min(dp[i][0], min(dp[i-1][0], dp[i-1][1]) ); if( flag0 && !flag1 ) dp[i][0] = min(dp[i][0], dp[i-1][0]); if( !flag0 && flag1 ) dp[i][0] = min(dp[i][0], dp[i-1][1]); if( !flag0 && !flag1 ) dp[i][0] = INF; flag0 = judge(Rstr[i], str[i-1]); flag1 = judge(Rstr[i], Rstr[i-1]); if( flag0 && flag1 ) dp[i][1] = min(dp[i][1], min(dp[i-1][0], dp[i-1][1])+cost[i] ); if( flag0 && !flag1 ) dp[i][1] = min(dp[i][1], dp[i-1][0]+cost[i] ); if( !flag0 && flag1 ) dp[i][1] = min(dp[i][1], dp[i-1][1]+cost[i] ); if( !flag0 && !flag1 ) dp[i][1] = INF; //cout << flag0 << " " << flag1 << endl; //cout << dp[i][0] << " " << dp[i][1] << endl; } } int main() { while(~scanf("%d", &n)) { for(int i=1;i<=n;i++) scanf("%I64d", &cost[i]); for(int i=1;i<=n;i++) { cin >> str[i]; } solve(); LL ans = min(dp [0], dp [1]); if(ans >= INF) cout << -1 << endl; else cout << ans << endl; } //system("pause"); }
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android dpi,dip,dp的概念以及屏幕适配
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- 关于UI切图与开发 px和dp
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games