D题求指导(附注释)
#include<bits/stdc++.h> using namespace std; int main(){ int n,x,y; cin>>n>>x>>y; string s; cin>>s; vector<int>cnt_one,cnt_zero; for(int i=0;i<n;i++){ if(s[i]=='1'){ cnt_one.push_back(i);//统计字符1的位置 } else{ cnt_zero.push_back(i);//统计字符0的位置 } } vector<long long>dp(n,LLONG_MAX); int cnt_0=0,cnt_1=0;//遍历过程中遇到字符的个数,以此找最近的字符 dp[0]=0; if(s[0]=='1'){//第一个先算 cnt_1++; } else{ cnt_0++; } //相同 x //不相同 y for(int i=1;i<n;i++){ char c=s[i]; if(c=='1'){//字符为1时 int pre=cnt_1-1;//前面的字符1在cnt_one位置即cnt_1-1 int pos=cnt_0-1;//前面的字符0在cnt_zero中的数量即cnt_0; if(pre<0){//前面没有相同字符即位置不合法 dp[i]=dp[cnt_zero[pos]]+y;//前面必有不同字符,直接转移 } else{//有相同字符时,这时候需要考虑前面是否有不同字符 if(pos<0){//前面无不同字符,直接由相同字符转移 dp[i]=dp[cnt_one[pre]]+x; } else{//两者都有,取最小转移 dp[i]=min(dp[cnt_zero[pos]]+y,dp[cnt_one[pre]]+x); } } cnt_1++;//这时候字符数量++; } else{ int pre=cnt_0-1; int pos=cnt_1-1; if(pre<0){ dp[i]=dp[cnt_one[pos]]+y; } else{ if(pos>=0) dp[i]=min(dp[cnt_one[pos]]+y,dp[cnt_zero[pre]]+x); else dp[i]=dp[cnt_one[pos]]+y; } cnt_0++; } } cout<<dp[n-1]<<endl; }
感觉没问题