18多校组队训练

G 容斥原理推公式或者打表oeis

公式推导:fn表示n个元素的排列方案

  现在加入了元素n+1,即求fn+1的排列方案

  设fn的一种合法排列是 1,,p2,p3,p4...pn,那么将n+1插到n-1个空隙中,其中有个空隙是不能插的,所以有n-2种插法

  由于新加入了n+1,所以n个元素某些不合法的排列也可以变成合法的状态

  那么n个元素的不合法的方案肯定是两个相邻元素在一起的时候,

  用n+1将这两个元素隔开,那么i,n+1,i+1就变成了一个整体..

  类推出公式

  https://blog.csdn.net/qq_37025443/article/details/82018108

  官方的容斥原理

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int t,n;
int m1[2010];
int m2[2010];
int m3[5000];
int main()
{
    scanf("%d",&t);
    while(t--){
       scanf("%d",&n);
       if(n==0){
            printf("1
");
            continue;
       }
       m1[1]=1;
       m2[1]=2;
       int a=1,b=1;
       int c;
       for(int k=1;k<=n;k++){    
         for(int i=1;i<=a;i++){
             for(int j=1;j<=b;j++){
                m3[i+j-1]=m3[i+j-1]+m1[i]*m2[j];
                m3[i+j]=m3[i+j-1]/10+m3[i+j];
                m3[i+j-1]=m3[i+j-1]%10;
              }
           }
         c=a+b+1;
         while(m3[c]==0&&c!=1) c--;
         a=c;m1[0]=c;
         for(int i=1;i<=c;i++) m1[i]=m3[i];
         memset(m3,0,sizeof(m1));   
       }
       for(int i=c;i>=1;i--) printf("%d",m1[i]);
       printf("
");           
   }
}
View Code

H 队友做的没看

I 队友做的没看

J 状态压缩+贪心

  把每把枪的(1+1+5=7)个属性压成七位状态,然后枚举状态,0是-,1是+

  然后贪心求每个状态下的主武器的最大值和对应反状态下的副武器的最大值,相加即可

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
#define ll long long 
ll k,n,m,mw[1<<8],sw[1<<8];
ll xm[maxn][8];//主武器六项属性 
ll xs[maxn][8];//副武器六项属性 

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(xm,0,sizeof xm);
        memset(xs,0,sizeof xs);
        scanf("%lld%lld%d",&n,&m,&k);
        for(int i=1;i<=n;i++){
            scanf("%lld",&xm[i][0]);
            for(int j=0;j<k;j++)
                scanf("%lld",&xm[i][j+2]);
        }
        for(int i=1;i<=m;i++){
            scanf("%lld",&xs[i][1]);
            for(int j=0;j<k;j++)
                scanf("%lld",&xs[i][j+2]);
        }
        for(int S=0;S<(1<<7);S++){
            mw[S]=sw[S]=-0x3f3f3f3f;
        }
        for(int i=1;i<=n;i++){//处理主武器 
            for(int S=0;S<(1<<7);S++){//枚举状态s 
                ll tmp=0;
                for(int k=0;k<=6;k++){
                     if(S & (1<<k))
                         tmp+=xm[i][k];    
                     else tmp-=xm[i][k];
                }
                mw[S]=max(tmp,mw[S]);
            }
        }
        
        for(int i=1;i<=m;i++){//处理副武器 
            for(int S=0;S<(1<<7);S++){//枚举状态s 
                ll tmp=0;
                for(int k=0;k<=6;k++){
                     if(S & (1<<k))
                         tmp+=xs[i][k];    
                     else tmp-=xs[i][k];
                }
                sw[S]=max(tmp,sw[S]);
            }
        }
        
        ll ans=0;
        for(int S=0;S<(1<<7);S++)
            ans=max(ans,mw[S]+sw[(1<<7)-1-S]);
        cout<<ans<<endl;
    }    
}
View Code

 待补题 E

原文地址:https://www.cnblogs.com/zsben991126/p/10713803.html