Educational Codeforces Round 57 (Rated for Div. 2) D. Easy Problem ###K //K

题目链接:https://codeforces.ml/contest/1096/problem/D
题意:给一段字符串 删除每个字符的值为a[i]  问如何删除 使得剩下的字符串 中的子序列(不一定连续)不含hard 求最小值  
思路:并不能如何确定最优 所以考虑dp来做 dp[i][j] 为前i个字符 不包含前j个子串的最小值

那么状态转移有两种, 如果当前的字符不是hard 的字符之一 那么dp[i][j] =dp[i-1][j]  直接转移

否则的话 有删除和不删除的两种情况   如果删除的话 就是dp[i-1][j]+a[i]  保留前一段, 不删除的话就是 只能用前一段的j-1 个字符串 再拼接当前这个

所以 dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+a[i])  

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define pb push_back
 4 #define ll long long
 5 const int maxn=1e5+10;
 6 const int mod=1e9+7;
 7 int a[maxn];
 8 ll dp[maxn][5];
 9 
10 string t="1hard";
11 
12 
13 int main()
14 {
15     ios::sync_with_stdio(0);
16     cin.tie(0);
17     int n;
18     cin>>n;
19     string s;
20     cin>>s;
21     for(int i=1;i<=n;i++)
22     {
23         cin>>a[i];
24     }
25     for(int i=0;i<=n;i++)
26     {
27         for(int j=0;j<=4;j++)
28             dp[i][j]=1e18;
29     }
30     for(int i=1;i<=4;i++)
31         dp[0][i]=0;
32     for(int i=1;i<=n;i++)
33     {
34         for(int j=1;j<=4;j++)
35         {
36             if(s[i-1]==t[j])
37                 dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+a[i]);
38             else
39                 dp[i][j]=dp[i-1][j];
40         }
41     }
42     cout<<dp[n][4]<<'\n';
43 
44 
45 
46 
47 
48 
49 
50 
51 }
View Code

 

dp[i][j] 前i个字符串中只出现到前j个的hard的最小贡献

 1 #include <bits/stdc++.h>
 2 #define double long double
 3 #define lb long double
 4 #define ll long long
 5 #define pi pair<int,int>
 6 #define fi first
 7 #define sc second
 8 #define pb push_back
 9 using namespace std;
10 const int maxn=1e5+10;
11 const int mod=1e9+7;
12 
13 
14 char s[maxn];
15 ll dp[maxn][4];
16 ll a[maxn];
17 
18 
19 int main()
20 {
21     ios::sync_with_stdio(0);
22     cin.tie(0);
23     int n;
24     cin>>n;
25     cin>>(s+1);
26     for(int i=1;i<=n;i++) cin>>a[i];
27     map<char,int>mp;
28     mp['h']=1;
29     mp['a']=2;
30     mp['r']=3;
31     mp['d']=4;
32     memset(dp,0x3f,sizeof(dp));
33     dp[0][0]=0;
34     for(int i=1;i<=n;i++)
35     {
36         int x=mp[s[i]];
37         if(x==0) x=100;
38         for(int j=0;j<4;j++)
39         {
40             if(j==x-1)
41             {
42                 dp[i][j]=dp[i-1][j]+a[i];
43             }
44             else if(j==x)
45             {
46                 dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]);
47             }
48             else
49             {
50                 dp[i][j]=dp[i-1][j];
51             }
52         }
53     }
54     ll ans=1e18;
55     for(int i=0;i<4;i++) ans=min(ans,dp[n][i]);
56     cout<<ans<<'\n';
57 
58 
59 
60 
61 
62 
63 }
View Code

 

posted @ 2020-11-13 22:04  canwinfor  阅读(93)  评论(0)    收藏  举报