1. 程式人生 > 實用技巧 >[USACO12MAR]Cows in a Skyscraper G

[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');}