zoukankan      html  css  js  c++  java
  • ZR#954 分组

    ZR#954 分组

    解法:

    设 $ f[i][a][b] $ 表示考虑了排序后的前 $ i $ 个人,目前已经有 $ a $ 个组配好了,还有 $ b $ 个组只有组员没有组长的最小代价。转移时,考虑当前的人是作为组长,加入一个已经有组员的组,还是作为组员新建一个组即可。
    然后对于有的人重要程度相同的情况,我们需要想办法继续保证组长在组员的后面。则对于重要程度相同的两个人,我们按照他们的志愿排序:先是只能当组员的,然后是都可以的,然后是只能当组长的。
    时间复杂度:$ O(nk^2) $ ,可以通过前 3 个子任务。
    然后因为如果 $ k imes 2 > n $ ,一定无解,所以特判一下就好了。

    CODE:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    #define LL long long
    #define N 1001000
    #define INF 0x3f3f3f3f3f3f3f3fll
    
    LL n,k,f[2][1010][1010];
    struct Neo {
        LL w,s,p;
    }a[N];
    
    inline bool cmp(Neo x,Neo y) {
        if(x.w != y.w) 
            return x.w < y.w;
        return x.p < y.p;
    }
    
    int main() {
        scanf("%lld%lld",&n,&k);
        for(int i = 1 ; i <= n ; i++) {
    		scanf("%lld%lld%lld",&a[i].w,&a[i].s,&a[i].p);
    		if(a[i].p == 1) a[i].p = 3;
    		else if(a[i].p == 2) a[i].p = 1;
    		else if(a[i].p == 3) a[i].p = 2;
    	}
        if(2 * k > n) {
            puts("-1");
            return 0;
            //system("pause");
        }
        sort(a+1,a+n+1,cmp);
        memset(f,0x3f,sizeof(f));
        f[0][0][0] = 0;
        int now = 1,las = 0;
        for(int i = 1 ; i <= n ; i++) {
    	    for(int j = 0 ; j <= k ; j++) {
    		    for(int l = 0 ; j + l <= k ; l++) {
    			    f[now][j][l] = f[las][j][l];
    			    if(a[i].p < 3) {
    		    		if(l >= 1) f[now][j][l] = min(f[now][j][l],f[las][j][l - 1] + a[i].s);
    		    	}
    			    if(a[i].p > 1) { 
    			    	if(j >= 1) f[now][j][l] = min(f[now][j][l],f[las][j - 1][l + 1]+a[i].s);
    			    }
    		    }
    	    }
    		swap(now,las);
    	}
        if(f[las][k][0] >= INF) {
            puts("-1");
            return 0;
        }
        printf("%lld 
    ",f[las][k][0]);
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    awk 连接字符串
    VCF (Variant Call Format)格式详解
    Extracting info from VCF files
    JAVA中AES对称加密和解密
    关于Java中常用加密/解密方法的实现
    Java的MD5加密和解密
    java实现MD5加密
    Java中String和byte[]间的转换浅析
    Java中字符串和byte数组之间的相互转换
    字符串与byte[]之间的转换
  • 原文地址:https://www.cnblogs.com/Repulser/p/11448937.html
Copyright © 2011-2022 走看看