• codeforces626F


    CF626F Group Projects

     有n个学生,每个学生有一个能力值ai。现在要把这些学生分成一些(任意数量的)组,每一组的“不和谐度”是该组能力值最大的学生与能力值最小的学生的能力值的差。求所有不和谐度之和不超过k的分组方案总数。

    输入输出样例

    输入 #1
    3 2
    2 4 5
    
    输出 #1
    3
    
    输入 #2
    4 3
    7 8 9 10
    
    输出 #2
    13
    
    输入 #3
    4 0
    5 10 20 21
    
    输出 #3
    1

    hint:n<=200,k<=1000

    sol:

    把a排序
    注意到不和谐度一定是一个终点的值-起点的值,中间可能还有几个非终非起的点,随便放即可
    dp[i,j,k]表示前i个数,还有j个起点未匹配,当前总贡献为k个方案数
    转移就是枚举当前点做起点,中间点,终点


    然后就会挂的很惨,有一种很坑的东西,就是一个点既是起点又是终点

    /*
    把a排序
    注意到不和谐度一定是一个终点的值-起点的值,中间可能还有几个非终非起的点,随便放即可 
    dp[i,j,k]表示前i个数,还有j个起点未匹配,当前总贡献为k个方案数
    转移就是枚举当前点做起点,中间点,终点 
    然后就会挂的很惨,有一种很坑的东西,就是一个点既是起点又是终点 
    */
    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0; bool f=0; char ch=' ';
        while(!isdigit(ch))    {f|=(ch=='-'); ch=getchar();}
        while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0) {putchar('-'); x=-x;}
        if(x<10) {putchar(x+'0'); return;}
        write(x/10); putchar((x%10)+'0');
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int Mod=1000000007,N=205;
    int n,m,a[N];
    int dp[2][N][1005];
    inline void Ad(int &x,int y)
    {
        x+=y; x-=(x>=Mod)?Mod:0;
    }
    int main()
    {
        freopen("codeforces626F_data.in","r",stdin);
        int i,j,k,t;
        R(n); R(m);
        for(i=1;i<=n;i++) R(a[i]);
        sort(a+1,a+n+1);
        dp[t=0][0][0]=1;
        for(i=1;i<=n;i++)
        {
            t^=1;
            for(j=0;j<=min(i,n>>1);j++)
            {
                int oo=a[i]-a[i-1];
                for(k=0;k<=m;k++)
                {
                    dp[t][j][k]=0;
                    if(j&&k>=(j-1)*oo) Ad(dp[t][j][k],dp[t^1][j-1][k-(j-1)*oo]);
                    if(k>=j*oo) Ad(dp[t][j][k],1LL*dp[t^1][j][k-j*oo]*j%Mod);
                    if(k>=(j+1)*oo) Ad(dp[t][j][k],1LL*dp[t^1][j+1][k-(j+1)*oo]*(j+1)%Mod);
                    if(k>=j*oo) Ad(dp[t][j][k],dp[t^1][j][k-j*oo]);
                }
            }
        }
        int ans=0;
        for(i=0;i<=m;i++) Ad(ans,dp[t][0][i]);
        Wl(ans);
        return 0;
    }
    View Code
  • 相关阅读:
    set转成toarray()
    list和set的拉拉扯扯的关系
    【转载】VNC和远程桌面的区别
    笔记本最小安装centos7 连接WiFi的方法
    mysql 索引优化 性能调优 锁
    PageHelper 自动去掉排序参数问题
    抽奖算法 百万次抽奖 单线程环境下 约 3.5 秒
    gitlab 安装和使用
    sharding sphere 分表分库 读写分离
    mycat 安装 分表 分库 读写分离
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/11279610.html
Copyright © 2020-2023  润新知