codeforces百题计划第一周(3)
很典型的选择或者不选的线性dp。
两个状态,选择:dp[i][1],不选:dp[i][0]
状态转移也很容易,就在i-1的基础上考虑(详见代码)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=1e5+5; 5 typedef long long ll; 6 const ll INF=1e18; 7 string s[maxn]; 8 string r[maxn]; 9 ll c[maxn]; 10 ll num[maxn]; 11 ll dp[maxn][2];//换或者不换两种状态 12 int main(){ 13 14 int n;cin>>n; 15 for(int i=0;i<=n;i++) 16 { 17 for(int j=0;j<=1;j++) 18 dp[i][j]=INF; 19 } 20 for(int i=1;i<=n;i++) cin>>c[i]; 21 for(int i=1;i<=n;i++) 22 { 23 cin>>s[i];num[i]=s[i].size(); 24 r[i]=s[i]; 25 reverse(r[i].begin(),r[i].end()); 26 } 27 /*for(int i=2;i<=n;i++) 28 { 29 if(num[i]<num[i-1]) 30 { 31 cout <<-1; 32 return 0; 33 } 34 }*/ 35 dp[1][0]=0;dp[1][1]=c[1]; 36 for(int i=2;i<=n;i++){ 37 if(s[i]>=s[i-1]) 38 { 39 dp[i][0]=dp[i-1][0]; 40 } 41 if(s[i]>=r[i-1]) 42 { 43 dp[i][0]=min(dp[i-1][1],dp[i][0]); 44 } 45 if(r[i]>=s[i-1]) 46 { 47 dp[i][1]=dp[i-1][0]+c[i]; 48 } 49 if(r[i]>=r[i-1]) 50 { 51 dp[i][1]=min(dp[i-1][1]+c[i],dp[i][1]); 52 } 53 if(dp[i][1]==INF&&dp[i][0]==INF) 54 { 55 cout <<-1<<endl; 56 return 0; 57 } 58 } 59 cout <<min(dp[n][1],dp[n][0])<<endl; 60 return 0; 61 }