Gray (dp 或 乱搞)

来源:互联网 发布:高端文玩淘宝店 编辑:程序博客网 时间:2024/06/13 02:18

10.10

思路
用dp[i][0/1]表示前i位在第i位时能得到的最大分数。

标解:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 200010;int n, a[N];char s[N];int f[N][2];int main(){    freopen("gray.in","r",stdin);    freopen("gray.out","w",stdout);        scanf("%s", s); n = strlen(s);        for(int i = 0; i < n; i++) scanf("%d", &a[i]);        memset(f, 0, sizeof(f));        if(s[0] == '1' || s[0] == '?') f[0][1] = a[0];        for(int i = 1; i < n; i++){            if((s[i] == '1' || s[i] == '?') && (s[i-1] == '0' || s[i-1] == '?'))                f[i][1] = std::max(f[i][1], f[i-1][0] + a[i]);            if((s[i] == '1' || s[i] == '?') && (s[i-1] == '1' || s[i-1] == '?'))                f[i][1] = std::max(f[i][1], f[i-1][1]);            if((s[i] == '0' || s[i] == '?') && (s[i-1] == '1' || s[i-1] == '?'))                f[i][0] = std::max(f[i][0], f[i-1][1] + a[i]);            if((s[i] == '0' || s[i] == '?') && (s[i-1] == '0' || s[i-1] == '?'))                f[i][0] = std::max(f[i][0], f[i-1][0]);        }        printf("%d\n", max(f[n-1][0], f[n-1][1]));    return 0;}

本人的乱搞(大模拟)
细节问题就自己看啦(估计也没人写这么蠢的方法了)

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define LL long long#define N 200010using namespace std;inline int read(){    int x = 0, f = 1; char ch = getchar();    while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); }    while(ch >= '0' && ch <= '9'){ x = x * 10 + ch - '0'; ch = getchar(); }    return x * f;}int a[N], ans=0;char s[N];int main(){    freopen ("gray.in", "r", stdin);    freopen ("gray.out", "w", stdout);    scanf("%s", s+1);    int len = strlen( s+1 );    for(register int i=1; i<=len; i++){        a[i] = read();        if(s[i] != '?'){            if(i == 1) ans += (s[i] - '0') * a[i];            else ans += ((s[i] - '0') ^ (s[i-1] - '0')) * a[i];        }        else{            int lf = s[i-1] - '0', rg, minn = a[i], S = 1, flag = 0; ans += a[i];            if(i == 1) flag = 1;            while(s[i+1] == '?') i++, scanf("%d", &a[i]), minn = min(minn, a[i]), S++, ans += a[i];            rg = s[i+1] - '0';            if(i == len) flag = 2;            else scanf("%d", &a[++i]), ans += a[i], minn = min(minn, a[i]);            if((S - (lf == rg)) % 2 != 0 && flag == 0) ans -= minn;            if(flag == 1 && (S + rg) % 2 == 0) ans -= minn;        }    }    printf("%d\n", ans);}
原创粉丝点击