Contest 3

  A:非常裸的dp。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define P 1000000007
#define N 32
int a,b,c,d,f[N][N][N][N][4];
void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
int main()
{
    freopen("count.in","r",stdin);
    freopen("count.out","w",stdout);
    a=read(),b=read(),c=read(),d=read();
    f[1][0][0][0][0]=f[0][1][0][0][1]=f[0][0][1][0][2]=f[0][0][0][1][3]=1;
    for (int i=1;i<a+b+c+d;i++)
        for (int x=0;x<=a;x++)
            for (int y=0;y<=b;y++)
                for (int z=0;z<=c;z++)
                {
                    int t=i-x-y-z;
                    if (t>d) continue;
                    for (int p=0;p<4;p++)
                        for (int q=0;q<4;q++)
                        if (p!=q)
                        {
                            if (q==0&&x<a) inc(f[x+1][y][z][t][q],f[x][y][z][t][p]);
                            if (q==1&&y<b) inc(f[x][y+1][z][t][q],f[x][y][z][t][p]);
                            if (q==2&&z<c) inc(f[x][y][z+1][t][q],f[x][y][z][t][p]);
                            if (q==3&&t<d) inc(f[x][y][z][t+1][q],f[x][y][z][t][p]);
                        }
                }
    cout<<((f[a][b][c][d][0]+f[a][b][c][d][1])%P+(f[a][b][c][d][2]+f[a][b][c][d][3])%P)%P;
    return 0;
}
View Code

  B:非常裸的组合。我又学傻了第一眼居然容斥还好拍了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define N 200010
#define P 1000000007
int n,m,k,ans=0,fac[N],inv[N];
int C(int n,int m){return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
int main()
{
    freopen("array.in","r",stdin);
    freopen("array.out","w",stdout);
    n=read(),m=read(),k=read();
    fac[0]=1;for (int i=1;i<=n+m;i++) fac[i]=1ll*fac[i-1]*i%P;
    inv[0]=inv[1]=1;for (int i=2;i<=n+m;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
    for (int i=1;i<=n+m;i++) inv[i]=1ll*inv[i]*inv[i-1]%P;
    if (m-k&1) {cout<<0;return 0;}
    cout<<1ll*C(n,k)*C((m-k>>1)+n-1,n-1)%P;
    return 0;
}
View Code

  C:非常裸的meet in the middle。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define N 300010
#define ll long long
int n,b[40];
ll a[2][N],l,r,ans,m;
void dfs(int k,int n,int p,ll s)
{
    if (k>n) a[p][++a[p][0]]=s;
    else
    {
        dfs(k+1,n,p,s);
        dfs(k+1,n,p,s+b[k]);
    }
}
ll calc(ll k)
{
    ll s=0;int x=a[1][0];
    for (int i=1;i<=a[0][0];i++)
    {
        while (x&&a[1][x]+a[0][i]>k) x--;
        s+=x;
    }
    return s;
}
int main()
{
    freopen("subset.in","r",stdin);
    freopen("subset.out","w",stdout);
    n=read();cin>>m;
    for (int i=1;i<=n;i++) r+=(b[i]=read());
    dfs(1,n>>1,0,0);
    dfs((n>>1)+1,n,1,0);
    sort(a[0]+1,a[0]+a[0][0]+1);
    sort(a[1]+1,a[1]+a[1][0]+1);
    while (l<=r)
    {
        ll mid=l+r>>1;
        if (calc(mid)>=m) ans=mid,r=mid-1;
        else l=mid+1;
    }
    cout<<ans;
    return 0;
}
View Code

  result:300 rank1

原文地址:https://www.cnblogs.com/Gloid/p/9737677.html