题目链接:
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(' ');}