zoukankan      html  css  js  c++  java
  • HDU 5375 Gray code 格雷码(水题)

    题意:给一个二进制数(包含3种符号:'0'  '1'  '?'  ,问号可随意 ),要求将其转成格雷码,给一个序列a,若转成的格雷码第i位为1,则得分+a[i]。求填充问号使得得分最多。

    思路:如果了解格雷码的转换,相信能很快看出一些端倪。偷别人的图:

          

      分析一下:所给的二进制数要转成格雷码,只与所给二进制有关。即不需要利用已经某些转换好的格雷码字。

      接下来分析5个位的串 :

      (1)00?00  仅有1个问号,只会与后面那些连续且非问号的串转成格雷码有关

      (2)00??0  有连续的1个问号,这才需要用到dp啊,因为所有问号有很多组合可能,但是他们满足:第i位只与前1位有关。所以仅需记录此位为0的结果,和为1的结果。

      (3)0?0?0  //问号不连续,按第1种处理。

      没有问号的串没有什么DP可言,直接转。

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int N=200010;
    
    char str[N];
    int a[N];
    int dp[N][2];   //结果只有两种,第i位为0/1
    
    int get_sum(int pos, int cur)//选个大的前缀,但并不需要关心其究竟是多少
    {
        int ans1=dp[pos-1][0]+ (0^cur)*a[pos];  //选0试试
        int ans2=dp[pos-1][1]+ (1^cur)*a[pos];  //选1试试
        return max(ans1, ans2);
    }
    
    int cal(int n)
    {
        memset(dp, 0, sizeof(dp));
        if(str[0]=='1' || str[0]=='?')        dp[0][1]= a[0];
        for(int i=1; i<n; i++)
        {
            int t=str[i]-'0';         //当前
            int p=str[i-1]-'0';     //前一位
            if( str[i]=='?' && str[i-1]=='?' )
            {
                dp[i][0]=get_sum(i, 0) ;
                dp[i][1]=get_sum(i, 1) ;
            }
            if( str[i]=='?' && str[i-1]!='?' )
            {
                dp[i][0]= dp[i-1][p] +( p^0) *a[i];  //前面是固定的,没啥好选。
                dp[i][1]= dp[i-1][p] +( p^1) *a[i];
            }
            if( str[i]=='0' || str[i]=='1')
            {
                if(str[i-1]=='?')    //前面是问号,取大者即可。
                    dp[i][t]=max( dp[i-1][0]+ (0^t)*a[i], dp[i-1][1]+ (1^t)*a[i] );
                else
                    dp[i][t]= dp[i-1][p]+ (p^t)*a[i];
            }
        }
        return max(dp[n-1][0], dp[n-1][1]);
    }
    
    int main()
    {
        freopen("input.txt", "r", stdin);
        int t, tmp, j=0;
        char c;
        cin>>t;
        while(t--)
        {
            scanf("%s", str);
            int len=strlen(str);
            for(int i=0; i<len; i++)    scanf("%d", &a[i]);
    
            printf("Case #%d: %d
    ", ++j,  cal(len) );
        }
        return 0;
    }
    AC代码
  • 相关阅读:
    《RESTful Web Services》第一章 使用统一接口
    selenium测试(Java)--元素操作(五)
    selenium测试(Java)--浏览器控制(四)
    Struts2 基础典型应用
    Fitnesse 访问日志配置
    selenium定位方法(java实例)(二)
    selenium测试环境搭建(一)
    java web 学习-网络资源
    eclipse + tomcat 开发环境配置
    HTTP客户端代码片段
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4722637.html
Copyright © 2011-2022 走看看