zoukankan      html  css  js  c++  java
  • 洛谷P1633 二进制

    P1633 二进制

    题目描述

    有三个整数A、B、C,以下用N(2)表示N的二进制(没有前导0)。

    设A(2)、B(2)、C(2)的最大长度为L,你需要构造三个正整数X、Y、Z,满足以下条件:

    (1) X(2)、Y(2)、Z(2)的长度都不超过L。

    (2) A(2)与X(2)中1的个数相同。

    (3) B(2)与Y(2)中1的个数相同。

    (4) C(2)与Z(2)中1的个数相同。

    (5) X+Y=Z.。

    输入输出格式

    输入格式:

    第一行包含一个正整数T,表示有T组测试数据。

    接下来T行,每行三个正整数A、B、C。

    【数据规模】

    对于30%的数据中,满足1<=A、B、C<=100;

    对于100%的数据中,满足1<=T<=10,1<=A、B、C<=2^30。

    输出格式:

    输出共T行,每行一个答案。

    输出最小的Z。如果没有z则输出-1

    输入输出样例

    输入样例#1:
    4
    7 6 9
    1 1 1
    1 1 4
    3 3 9
    输出样例#1:
    10
    -1
    2
    6
    /*
        我们考虑三个长度为l的串;
        显然如果这3个串符合条件的话;
        我们就只要保证增加2^l级别的值满足加法原则就好了;
        所以我们大力dp;
        f[i][a][b][c][0/1]
        i表示位数
        a表示x串前i-1个字符所有的1的数量;
        b,c同理;
        0/1表示c串在第i位是1还是0;
        预处理
        f[1][0][0][0][0]=0;其他都是inf;
        转移就是考虑当前第i位a,b要不要放1;
        然后对应的计算c新增的值;
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N 35
    long long f[N][N][N][N][2],a1,b1,c1;
    int T,n;
    int l(long long x){
        int cnt1=0,cnt2=0;
        while(x){
            cnt1++;
            if(x&1)cnt2++;
            x>>=1;
        }
        n=max(n,cnt1);
        return cnt2;
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            cin>>a1>>b1>>c1;n=0;
            int A=l(a1),B=l(b1),C=l(c1);
            memset(f,127/3,sizeof(f));
            f[1][0][0][0][0]=0;
            for(int i=1;i<=n;i++){
                for(int a=0;a<=A;a++)
                for(int b=0;b<=B;b++)
                for(int c=0;c<=C;c++){
                    long long v=f[i][a][b][c][0];
                    f[i+1][a][b][c][0]=min(f[i+1][a][b][c][0],v);
                    f[i+1][a+1][b+1][c][1]=min(f[i+1][a+1][b+1][c][1],v+(1<<i));
                    f[i+1][a+1][b][c+1][0]=min(f[i+1][a+1][b][c+1][0],v+(1<<(i-1)));
                    f[i+1][a][b+1][c+1][0]=min(f[i+1][a][b+1][c+1][0],v+(1<<(i-1)));
                    v=f[i][a][b][c][1];
                    f[i+1][a][b][c+1][0]=min(f[i+1][a][b][c+1][0],v);
                    f[i+1][a+1][b+1][c+1][1]=min(f[i+1][a+1][b+1][c+1][1],v+(1<<i));
                    f[i+1][a+1][b][c][1]=min(f[i+1][a+1][b][c][1],v+(1<<(i-1)));
                    f[i+1][a][b+1][c][1]=min(f[i+1][a][b+1][c][1],v+(1<<(i-1)));
                }
            }
            if(f[n+1][A][B][C][0]>(1<<30))printf("-1
    ");
            else cout<<f[n+1][A][B][C][0]<<endl;
        }
    }
  • 相关阅读:
    在SharePoint中实现Workflow(2):创建一个Workflow
    pku1384PiggyBank(动态规划)
    pku1088滑雪(记忆性搜索)
    hdu1251统计难题(初次接触字典树)
    详细解说 STL 排序(Sort)
    pku1631Bridging signals(动态规划题+二分搜索)
    pku1157LITTLE SHOP OF FLOWERS(简单动态规划题:摆放鲜花使审美价值达到最高)
    pku1067取石子游戏(博弈)
    pku2524Ubiquitous Religions(初次接触并查集)
    pku1050To the Max(求矩阵的最大子段和)
  • 原文地址:https://www.cnblogs.com/thmyl/p/7465148.html
Copyright © 2011-2022 走看看