• bzoj4664: Count


    bzoj4498: 魔法的碰撞的哥哥题,我只写了一种

    不一样的地方在于贡献有负数,第三维要保存的不能仅仅是0~L,这样空间会炸裂

    考虑如何把贡献变成正的

    假如要求最优解,那么一定是按顺序排,混乱度为hmax-hmin

    反过来想,这启示我们hi-hj,可以用(hi - hi-1)+(hi-1 - hi-2)……(hj+1 - hj)表示出来

    那么可以从小到大插入,每次插入给所有段的两端的点的贡献加上hi - hi-1

    好妙啊

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int _=1e2;
    const int maxn=1e2+10;
    const int maxL=1e3+_;
    const LL mod=1e9+7;
    
    int h[maxn];
    LL f[2][maxn][maxL][3];
    int main()
    {
    //    freopen("b.in","r",stdin);
    //    freopen("b.out","w",stdout);
        int n,L;
        scanf("%d%d",&n,&L);
        if(n==1){puts("1");return 0;}
        for(int i=1;i<=n;i++)scanf("%d",&h[i]);
        sort(h+1,h+n+1);
        if(h[n]-h[1]>L){puts("0");return 0;}
        
        int now=0;
        f[now][1][0][0]=1;
        f[now][1][0][1]=2;
        for(int i=1;i<n;i++)
        {
            memset(f[now^1],0,sizeof(f[now^1]));
            for(int j=1;j<=i;j++)
                for(int k=0;k<=L;k++)
                    for(int p=0;p<=2;p++)
                        if(f[now][j][k][p])
                        {
                            int d=k+(h[i+1]-h[i])*(2*j-p);
                            if(d<=L)
                            {
                                f[now^1][j+1][d][p]=(f[now^1][j+1][d][p]+f[now][j][k][p]*(j-p+1))%mod;
                                f[now^1][j][d][p]=(f[now^1][j][d][p]+f[now][j][k][p]*(2*j-p))%mod;
                                if(j!=1)f[now^1][j-1][d][p]=(f[now^1][j-1][d][p]+f[now][j][k][p]*(j-1))%mod;
                                if(p!=2)
                                {
                                    f[now^1][j+1][d][p+1]=(f[now^1][j+1][d][p+1]+f[now][j][k][p]*(2-p))%mod;
                                    f[now^1][j][d][p+1]=(f[now^1][j][d][p+1]+f[now][j][k][p]*(2-p))%mod;
                                }
                            }
                        }
            now^=1;
        }
        
        LL ans=0;
        for(int i=0;i<=L;i++)
            ans=(ans+f[now][1][i][2])%mod;
        printf("%lld
    ",ans);
        
        return 0;
    }
  • 相关阅读:
    Exception和Error有什么区别?
    网络流量劫持的含义
    安全术语:
    加载相关
    10、接到任务后的整个测试前准备流程总结
    fiddler工具栏数据解释
    HTTP的请求头标签 If-Modified-Since
    VueStudyDemo
    Vue从入门到放弃
    TypeScript初体验
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10439832.html
Copyright © 2020-2023  润新知