• 51nod 1406 与查询


    垃圾选手练dp

    考虑对于一个数,能够把它表示出来也一定可以把它某些1的位变成0变成的数表示出来

    那么用大的数更新小的,容易想到每次都把这个大的数的1个1的位变成0

    但是这样还是会有重复的情况

    比如10010被10110和11010更新,但是这两个数都会被11110更新到

    那么DP再加一维,f[i][zt]表示zt这个数当前只受到前i位是1的数的更新,对于前i-1位的更新可以直接加上,第i位的更新在当前的for循环里面处理

    这样就不会重复了,同时可以发现这个是一个类似背包的东西,所以i的那维也可以省掉了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    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;
    }
    void write(int d)
    {
        if(d<0){putchar('-');d=-d;}
        if(d>=10)write(d/10);
        putchar(d%10+'0');
    }
    
    int f[1100000];
    int main()
    {
        int n,x,mx=0;
        n=read();
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++)
        {
            x=read(),f[x]++;
            mx=max(mx,x);
        }
            
        for(int i=22;i>=0;i--)
            for(int zt=1;zt<=mx;zt++)
                if(zt&(1<<i))f[zt^(1<<i)]+=f[zt];
        
        f[0]=n;
        for(int i=0;i<=30;i++)
        {
            write(f[i]);
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    Paths on a Grid
    Three Kingdoms(优先队列+bfs)
    Factstone Benchmark(数学)
    C. Searching for Graph(cf)
    B. Trees in a Row(cf)
    String Successor(模拟)
    乘积最大的分解(数学)
    Kindergarten Election
    In 7-bit
    Friends
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9768476.html
Copyright © 2020-2023  润新知