zoukankan      html  css  js  c++  java
  • NOIp模拟题 T1 篮球比赛1题解

    题面

    Czhou 为了提高机房里各种神牛的身体素质,决定在每次训练后举行篮球比赛。为了保持比赛公平,Czhou 要将神牛们分成两队。首先神牛们赛前都要排成固定的队伍;然后 Czhou将队伍分成一半(前一半和后一半队伍人数可以不等),再分别从两个队伍中选出一些人进行篮球比赛。为了保持公平性,Czhou 要求第一个队伍参加比赛的神牛能力的 XOR 值等于第二个队伍参加比赛的神牛能力的 and 值。为了增加比赛趣味,每次比赛的参加神牛们不能一样,Czhou 现在想知道可以举办多少天的比赛。(很明显参加比赛的人数不能为 0)

    Xor 即为亦或, (0 xor 0 = 0), (0 xor 1 = 1), (1 xor 0 = 1) , (1 xor 1 = 0)

    And 即为与, (0 and 0 = 0) , (0 and 1 = 0) , (1 and 0 = 0) , (1 and 1 = 1)

    举个例子 (10 and 2 = 10)(10 xor 2 = 8)(10 = (1010)_2)(2 = (10)_2)(8 =(1000)_2)

    Input:basketball1.in
    第一行 n,表示机房有 n 个神牛。
    第二行有 n 个数 a_i,表示各个神牛的能力值,并且这是赛前各个神牛的排队方式。

    Output: basketball1.out
    就一个数字,表示可以举办多少天比赛。由于天数会比较多,输出结果模 1000000007。

    Sample1.input:

    3
    1 2 3
    

    Sample1.output

    1
    

    Sample2.input

    4
    1 2 3 3
    

    Sample2.output

    4
    

    样例 1 说明:1 xor 2 = 3

    样例 2 说明:可以举办四天比赛,参加比赛的双方队伍分别是(1,2)(3);(1,2)(3);(1,2)(3,3);(3)(3)这里虽然能力值相同,但是指的是不同的牛。对于(1,2)(3,3)来说,队伍分为两个队伍:(1,2)(3,3),再从各自队伍选出全部选手参加比赛对于(3)(3)来说,队列分为两个队伍:(1,2,3)(3),再从各自队伍中选出 3 进行比赛

    数据范围:
    (0 leq n leq 10^3)
    (0 leq a_i <1024)

    题解

    注意到异或和且运算的结果都不会超过(1024),所以可以dp。设(f_{i,j})表示第(i)个数在方案内且异或值为(j)时的方案数,(g_{i,j})则为且运算的相应方案数,不过且运算要倒着处理。然后状态转移方程也很好写,关键在于最后如果进行简单的乘法原理会漏掉或者多算某些情况。

    为了避免重复计算,我们一定要保证第(i)个数在方案内,这也是我们设计状态的原因。为了防止漏掉情况,再计算一下前(i)位的方案数前缀和,再使用乘法原理相乘即可。

    Code

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int mod=1e9+7;
    int n;
    int a[1005],b[1005];
    ll sum[3000],f[1005][3000],g[1005][3000];
    ll ans;
    int main()
    {
    	freopen("basketball1.in","r",stdin);
    	freopen("basketball1.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	for(int i=1;i<=n;i++){
    		b[i]=a[n-i+1];
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=0;j<1024;j++){
    			f[i][j]=(f[i][j]+sum[j^a[i]])%mod;
    		}
    		f[i][a[i]]=(f[i][a[i]]+1)%mod;
    		for(int j=0;j<1024;j++){
    			sum[j]=(sum[j]+f[i][j])%mod;
    		}
    	}
    	memset(sum,0,sizeof(sum));
    	for(int i=0;i<n;i++){
    		for(int j=0;j<1024;j++){
    			g[i+1][j&b[i+1]]=(g[i+1][j&b[i+1]]+sum[j])%mod;
    		}
    		g[i+1][b[i+1]]=(g[i+1][b[i+1]]+1)%mod;
    		for(int j=0;j<1024;j++){
    			sum[j]=(sum[j]+g[i+1][j])%mod;
    		}
    	}
    	memset(sum,0,sizeof(sum));
    	for(int i=1;i<n;i++){
    		for(int j=0;j<1024;j++){
    			sum[j]=(sum[j]+f[i][j])%mod;
    		}
    		for(int j=0;j<1024;j++){
    			ans=(ans+sum[j]*g[n-i][j])%mod;
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    route命令
    linux下限制ip访问
    linux安装oracle客户端
    Upgrading to Kentico 12
    online youtube subtitle downloader
    Driving continuous quality of your code with SonarCloud
    炉石传说 乱斗模式 三足鼎立
    Behavior-driven development
    TestNG like unit testing framework in C# (C sharp)
    Windows 10 & 8: Install Active Directory Users and Computers
  • 原文地址:https://www.cnblogs.com/57xmz/p/14416046.html
Copyright © 2011-2022 走看看