题目链接: https://codeforces.com/contest/1207/problem/C
思路:令dp[i][0]为i位置高度为1所能取的最小值,dp[i][1]为i位置高度为2所能取的最小值,然后如果高度有变化需要加a,知道这些就可以写出状态转移方程。
还有贪心的思路:题目中可以变化的区域只有0区域,这个区域要么全取1,要么全取2,部分取1部分取2是没有用的,因为它已经加入了2*a,不如全取1的方案。 有空会把这个思路的代码补上。
dp的代码:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int maxn = 2e5 + 5;
const ll INF = 2e18;
ll dp[maxn][3];
char s[maxn];
int main() {
int T;
ios::sync_with_stdio(0);
cin >> T;
while(T--) {
ll n , a ,b;
cin >> n >> a >> b;
cin >> s;
ll ans = 0;
memset(dp,0x7f,sizeof(dp));
if(s[0] == '0') {
dp[0][0] = b;
}
for(int i = 1 ; i <= n ; i++) {
if(i < n && s[i] == '1') {
dp[i][1] = min(dp[i - 1][0] + a + 2 * b, dp[i - 1][1] + 2 * b);
}
else {
dp[i][0] = min(dp[i - 1][1] + a + 2 * b , dp[i - 1][0] + b);
dp[i][1] = min(dp[i - 1][1] + 2 * b , dp[i - 1][0] + a + b);
}
}
ans = dp[n][0] + a * n;
cout << ans << "\n";
}
return 0;
}