• P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper


    P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper

    给出n个物品,体积为w[i],现把其分成若干组,要求每组总体积<=W,问最小分组。(n<=18)

    Solution

    数据范围识状压(其实迭代加深也可以, 答案不会超过18)
    每个状压状态有两个参数:
    (dp[i])(i) 状态的最少需要分几组
    (w[i])(i) 状态装的最少的最少承载多重

    根据贪心, 我们必然优先满足 (dp[i]) 较小, 在这个基础上再满足 (w[i]) 尽可能小
    那么大体框架就差不多定型了
    具体看注释

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define LL long long
    #define REP(i, x, y) for(int i = (x);i <= (y);i++)
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = (1 << 19);
    int num, W;
    int a[25], one[25];
    int dp[maxn], w[maxn];
    int main(){
    	num = RD(), W = RD();
    	REP(i, 1, num)a[i] = RD(), one[i] = (1 << (i - 1));
    	int maxstate = (1 << num) - 1;
    	REP(i, 0, maxstate)dp[i] = w[i] = 1e9;
    	dp[0] = 0;
    	REP(i, 0, maxstate){
    		REP(j, 1, num){
    			if(i & one[j])continue;
    			if(dp[i] <= dp[i | one[j]] && w[i] + a[j] <= W){//若是现在的状态还能放下j
    				dp[i | one[j]] = dp[i];//更新
    				w[i | one[j]] = min(w[i | one[j]], w[i] + a[j]);
    				}
    			else if(w[i] + a[j] > W && dp[i] + 1 <= dp[i | one[j]]){//放不下,但又能更新
    				dp[i | one[j]] = dp[i] + 1;
    				w[i | one[j]] = min(w[i | one[j]], a[j]);
    				}
    			}
    		}
    	printf("%d
    ", dp[maxstate]);
    	return 0;
    	}
    
  • 相关阅读:
    Codeforces Round #717 (Div. 2)
    Codeforces Round #716 (Div. 2)
    atCoder Regular Contest 117
    Codeforces Round #715 (Div. 2)
    牛客挑战赛49
    从零开始搭建webpack应用
    扫盲:npm
    MYSQL安装
    Int和integer区别
    关于JDK配置以及DOS窗口执行指令
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9762412.html
Copyright © 2020-2023  润新知