概述
题目链接 http://codeforces.com/contest/446/problem/A
题意,给出n个字符串,以及反转每个字符串的花费。
我们可以反转任意个字符串。
求我们反转一定数量的字符串后,使得字符串以字典序递增(不减)的最小花费。
题目思路:
对于每个字符串反转或不反转,可以只考虑他的上一个字符串。
设dp0[i] 表示,到第i个为止,不反转 i 的当前总花费。
dp1[i] 表示 到第i个为止,反转 i的当前总花费。
那么就可以找到状态转移方程。
然后,这道题比较复杂的是对字符串的处理,要用string对象存储。并且调用它的反转字符串的方法。
string已经重载了> >= < <=
就是用来比较字典序的。
代码如下:
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long LL;
typedef long long ll;
const int maxn = 1e5+6;
const int modn = 1e9+7;
const int INF = 0x3f3f3f3f;
string s[maxn];
ll dp0[maxn];
ll dp1[maxn];
int a[maxn];
void show(int a[],int n){
for(int i=0;i<n;i++){
printf("%3d ",a[i]);
}printf("n");
}
ll mymin(ll a,ll b){
if(a==-1)return b;
if(b==-1)return a;
return a<b?a:b;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++){
dp0[i] = dp1[i] = -1;
}
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++){
cin >> s[i];
}
dp0[0] = 0;
dp1[0] = a[0];
for(int i=1;i<=n;i++){
if(s[i]>=s[i-1]){//原来i大于原来i-1
dp0[i] = mymin(dp0[i-1],dp0[i]);
}
reverse(s[i-1].begin(),s[i-1].end());
if(s[i]>=s[i-1]){//原来i 大于 反转i-1
dp0[i] = mymin(dp0[i],dp1[i-1]);
}
reverse(s[i].begin(),s[i].end());
if(s[i]>=s[i-1]){//反转i 大于 反转i-1
if(dp1[i-1]!=-1)dp1[i] = mymin(dp1[i],dp1[i-1]+a[i]);
}
reverse(s[i-1].begin(),s[i-1].end());
if(s[i]>=s[i-1]){//反转i 大于 原来i-1
if(dp0[i-1]!=-1)dp1[i] = mymin(dp0[i-1]+a[i],dp1[i]);
}
reverse(s[i].begin(),s[i].end());
}
ll ans = mymin(dp0[n-1],dp1[n-1]);
printf("%I64dn",ans);
}
}
最后
以上就是机智牛排为你收集整理的codeforces 446C DZY Loves Sequences的全部内容,希望文章能够帮你解决codeforces 446C DZY Loves Sequences所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复