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 }
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 }

浙公网安备 33010602011771号