立命館合宿2012 day3 問題E Elevator (AOJ 2366)
制約条件
n≦10000
1≦m≦n
W≦10000
ki≦15
Σki≦15
wi≦W
方針
全ての荷物を一階ずつ運んで、全て降ろすと考えてもエレベーターの移動量は同じ。
荷物の集合Sが決まったとき、それらを全て一つ下の階へ降ろすのに必要なエレベーターの往復回数をdp[S]とすれば、
dp[S]=min{dp[s]+1 | 集合S-sの荷物は一度にエレベータに載る}
という漸化式がたち、
計算量O(3^n)のDPが出来る。
ソースコード
int n,m,w; int wi[15], nw; int bit[10000],sum[1<<15]; int dp[1<<15]; int main(){ cin>>n>>m>>w; rep(i,n){ int k; cin>>k; rep(j,k){ cin>>wi[nw]; bit[i]|=1<<nw++; } } rep(i,1<<nw)rep(j,nw)if(i&1<<j)sum[i]+=wi[j]; rep(i,1<<nw)dp[i]=inf; dp[0]=0; rep(i,1<<nw)for(int j=i;j;j=j-1&i){ if(sum[j]<=w)dp[i]=min(dp[i],dp[i-j]+1); } int top=0; rep(i,n)if(bit[i])top=i; if(top==0){ cout<<0<<endl; return 0; } int ans=abs(m-1-top), h=0; for(int i=top;i>0;i--){ h+=bit[i]; ans+=dp[h]*2-1; } cout<<ans<<endl; return 0; }