[USACO12MAR]Cows in a Skyscraper G

题目链接:

    P3052 [USACO12MAR]Cows in a Skyscraper G

 

题目大意:

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

solution:

  状压好题.由贪心策略,在dp转移时维护每个状态最大剩余空间,然后分类判断即可.

code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define R register
#define debug puts("mlg")
#define next exjfasaslfasfadfsaf
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writesp(ll x);
inline void writeln(ll x);
ll n,W;
ll w[20];
ll f[(1<<18)],g[(1<<18)];
int main(){
    n=read();W=read();
    memset(f,0x3f,sizeof f);
    f[0]=1;g[0]=W;
    for(R ll i=1;i<=n;i++) w[i]=read();
    for(R ll i=0;i<(1<<n);i++){
        for(R ll j=1;j<=n;j++){
            if(i&(1<<(j-1))) continue;
            if(g[i]>=w[j]&&f[i|(1<<(j-1))]>=f[i]){
                f[i|(1<<(j-1))]=f[i];
                g[i|(1<<(j-1))]=max(g[i|(1<<(j-1))],g[i]-w[j]);
            }
            else{
                if(g[i]<w[j]&&f[i|(1<<(j-1))]>f[i]){
                    f[i|(1<<(j-1))]=f[i]+1;
                    g[i|(1<<(j-1))]=max(g[i|(1<<(j-1))],W-w[j]);
                }
            }
        }
    }
    writeln(f[(1<<n)-1]);
} 
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
inline void writesp(ll x){write(x);putchar(' ');}
inline void writeln(ll x){write(x);putchar('\n');}

 

posted @ 2020-07-24 21:42  月落乌啼算钱  阅读(159)  评论(0编辑  收藏  举报