2015 多校联赛 ——HDU5375(dp)

Sample Input
2 00?0 1 2 4 8 ???? 1 2 4 8
 
Sample Output
Case #1: 12 Case #2: 15

?部分可以是0  or  1,将二进制转化成格雷码后,哪里是 1 就可以取相应的数,求得到数的最大值


①:判断连续的?的个数奇偶不同,两边是否相等。在有时会去掉一个最小值。(感觉写着很麻烦)

#include <iostream>
#include <cstdio>
#include <vector>
#include<cstring>
using namespace std;
char s[200010];
int a[200010];
int main()
{
    int k=1;
    int case0;
    scanf("%d",&case0);
    while(case0--)
    {
        scanf("%s",s);
        int leng=strlen(s);
        int i,j;
        for(i=0; i<leng; i++)
            scanf("%d",&a[i]);
        long long int ssum,sum;
        ssum=0;

        for(i=0;i<leng; i++)
        {
            if(s[i]=='?')
            {
                sum=0;
                int min1=0x3f3f3f3f;
                for(j=i; s[j]=='?'; j++)
                {
                    sum+=a[j];
                    if(min1>a[j])
                        min1=a[j];
                }
                if(s[j]!='')
                {
                    sum+=a[j];
                    if(min1>a[j])
                        min1=a[j];
                }
                if(i==0&&((s[j]=='1'&&(j-i)%2==1)||(s[j]=='0'&&(j-i)%2==0)))
                    sum-=min1;
                if(i!=0&&s[j]!='')
                {
                    if(s[i-1]==s[j]&&(j-i)%2==0)
                        sum-=min1;
                    if(s[i-1]!=s[j]&&(j-i)%2==1)
                        sum-=min1;
                }
                ssum+=sum;
                  i=j;

            }
            else if(i==0&&s[i]=='1')
                ssum+=a[i];
            else if(s[i]!=s[i-1]&&i!=0)
                ssum+=a[i];
        }
        printf("Case #%d: ",k++);
        cout<<ssum<<endl;
    }
    return 0;
}

  


②dp

dp[i][0]表示第i个位置上取0.

dp[i][0] = max(dp[i-1][0],dp[i-1][1]+a[i]);

既然能够得到 i 与 i - 1 的关系,自然推出。 


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 100010
using namespace std;
const int INF = 0x3f3f3f3f;
char s[200050];
int a[200050];
int dp[200050][2];
int main()
{
    int T;
    int cas = 1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",s);
        int len = strlen(s);
        for(int i = 0; i < len; i++)
            scanf("%d",&a[i]);
        dp[0][0] = dp[0][1] = -INF;

        if(s[0] == '0' || s[0] == '?')
            dp[0][0] = 0;
        if(s[0] == '1' || s[0] == '?')
            dp[0][1] = a[0];

        for(int i = 1;i < len;i++)
        {
            dp[i][0] = dp[i][1] = -INF;
            if(s[i] == '0' || s[i] == '?')
                dp[i][0] = max(dp[i-1][0],dp[i-1][1]+a[i]);
            if(s[i] == '1' || s[i] == '?')
                dp[i][1] = max(dp[i-1][0]+a[i],dp[i-1][1]);
        }

        printf("Case #%d: %d
",cas++,max(dp[len-1][0],dp[len-1][1]));
    }
    return 0;
}

  










原文地址:https://www.cnblogs.com/Przz/p/5409785.html