1. 程式人生 > 實用技巧 >Educational Codeforces Round 57 (Rated for Div. 2) D. Easy Problem

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

題目連結: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