• 联考20200722 T3 积木



    分析:
    先只考虑两种颜色,假设分别有\(A,B\)个,发现答案为\(\binom{A+B}{A}\)
    转化为\(A*B\)的网格上只能向右向下走,从左上角到右下角的方案数
    变成三种,分别有\(A,B,C\)个,答案为\(\binom{A+B+C}{A+B}\binom{A+B}{A}\)
    把网格变成\(A*B*C\)三维的就好了
    两堆积木\(i,j\)的贡献为\((-A_i,-B_i,-C_i)\)\((A_j,B_j,C_j)\)的方案数
    枚举是\(O(n^2)\)的且难以优化
    发现实际上\(A,B,C\)的范围很小,只有150
    那么网格规模只会有\(m=300\)的大小
    于是考虑把所有\((-A_i,-B_i,-C_i)\)的点值都加上1,直接DP求出来最后停留在每个点的方案数
    对于每个\(i\)得到停留在\((A_i,B_i,C_i)\)的方案数,最后每个点减去自己到自己的方案再除以2就是答案了
    直接暴力DP,复杂度\(O(m^3)\)

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    
    #define maxn 200005
    #define maxm 155
    #define INF 0x3f3f3f3f
    #define MOD 100000007
    #define eps 1e-10
    
    using namespace std;
    
    inline long long getint()
    {
    	long long num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n;
    int a[maxn],b[maxn],c[maxn];
    int f[maxm<<1][maxm<<1][maxm<<1];
    int C[maxm<<3][maxm<<3];
    
    inline int upd(int x){return x<MOD?x:x-MOD;}
    inline int ksm(int num,int k)
    {
    	int ret=1;
    	for(;k;k>>=1,num=1ll*num*num%MOD)if(k&1)ret=1ll*ret*num%MOD;
    	return ret;
    }
    
    int main()
    {
    	n=getint();
    	C[0][0]=1;
    	for(int i=1;i<maxm<<3;i++)
    	{
    		C[i][0]=1;
    		for(int j=1;j<=i;j++)C[i][j]=upd(C[i-1][j-1]+C[i-1][j]);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		a[i]=getint(),b[i]=getint(),c[i]=getint();
    		f[maxm-a[i]][maxm-b[i]][maxm-c[i]]++;
    	}
    	for(int i=1;i<maxm<<1;i++)for(int j=1;j<maxm<<1;j++)for(int k=1;k<maxm<<1;k++)
    		f[i][j][k]=upd(upd(f[i][j][k]+f[i-1][j][k])+upd(f[i][j-1][k]+f[i][j][k-1]));
    	int ans=0;
    	for(int i=1;i<=n;i++)ans=(ans+1ll*(f[a[i]+maxm][b[i]+maxm][c[i]+maxm]-(1ll*C[2*(a[i]+b[i]+c[i])][2*(a[i]+b[i])]*C[2*(a[i]+b[i])][2*a[i]]%MOD)+MOD)*ksm(2,MOD-2))%MOD;
    	printf("%d\n",ans);
    }
    

  • 相关阅读:
    PSFTP使用简单教程
    JavaMail应用--通过javamail API实现在代码中发送邮件功能
    java常用数据类型转换
    自己封装的Java excel数据读取方法
    java怎样实现重载一个方法
    怎样做好测试保证交付产品质量
    软件测试之测试用例颗粒度问题
    Python 一句命令启动一个web服务器
    ansible 模块之在学习--lineinfile
    centos 7 安装sql 审核工具 inception + archer
  • 原文地址:https://www.cnblogs.com/IzayoiDoyo/p/13366937.html
Copyright © 2020-2023  润新知