Codeforces 1096D-Easy Problem
Codeforces 1096D-Easy Problem
题意
给一个长度为n的字符串s,以及数组a,a[i]表示删除s[i]所需要的花费。问要让字符串s中不包含“hard”的子序列所需要的最小花费。
题解
dp[i][0]表示前i个字符中不包含'h'的最小花费,dp[i][1]表示前i个字符中不包含'ha'的最小花费...
那么如果当前字符为'h',可以得到递推式dp[i][0]=dp[i-1][0]+a[i],dp[i][1]=min(dp[i-1][0],dp[i-1][1]),如果当前字符为'a',可以得到dp[i][1]=dp[i-1][1]+a[i],dp[i][2]=min(dp[i-1][1],dp[i-1][2])...
考虑到二维数组只用到了两层,所以可以压缩到一层,变成一维dp。
代码1
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll a[N],dp[N][5];
int n;
char s[N];
int main(){
scanf("%d",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++){
if(s[i]=='h'){
dp[i][0]=dp[i-1][0]+a[i];
dp[i][1]=min(dp[i-1][0],dp[i-1][1]);
dp[i][2]=dp[i-1][2];
dp[i][3]=dp[i-1][3];
}else if(s[i]=='a'){
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][1]+a[i];
dp[i][2]=min(dp[i-1][1],dp[i-1][2]);
dp[i][3]=dp[i-1][3];
}else if(s[i]=='r'){
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][1];
dp[i][2]=dp[i-1][2]+a[i];
dp[i][3]=min(dp[i-1][2],dp[i-1][3]);
}else if(s[i]=='d'){
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][1];
dp[i][2]=dp[i-1][2];
dp[i][3]=dp[i-1][3]+a[i];
}else{
for(int j=0;j<=3;j++) dp[i][j]=dp[i-1][j];
}
}
ll ans=min(dp[n][0],min(dp[n][1],min(dp[n][2],dp[n][3])));
printf("%lld\n",ans);
return 0;
}
代码2
更简洁的写法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll a[N],dp[N][5];
int n;
char s[N],str[]="*hard";
int main(){
scanf("%d",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
memset(dp, 0x3f, sizeof dp);
for(int i = 1; i <= 4; i++) dp[0][i] = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=4;j++){
if(s[i]==str[j]) dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+a[i]);
else dp[i][j]=dp[i-1][j];
}
}
ll ans=min(dp[n][1],min(dp[n][2],min(dp[n][3],dp[n][4])));
printf("%lld\n",ans);
return 0;
}
代码3(一维)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll a[N],dp[5];
char s[N];
int n;
int main(){
scanf("%d",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++){
if(s[i]=='h'){
dp[0]+=a[i];
}else if(s[i]=='a'){
dp[1]=min(dp[0],dp[1]+a[i]);
}else if(s[i]=='r'){
dp[2]=min(dp[1],dp[2]+a[i]);
}else if(s[i]=='d'){
dp[3]=min(dp[2],dp[3]+a[i]);
}
}
ll ans=dp[3];
printf("%lld\n",ans);
return 0;
}

浙公网安备 33010602011771号