1. 程式人生 > >HDU 2159

HDU 2159

logs hdu str 方程 維護 中文 %d r++ i++

題目大意:中文題面。。

二維01背包問題,給出所需經驗值、忍耐度、種數、最大個數四個基本值,於是我們可以將最大個數作為第一維,第二維有兩種維護方法,這裏就給出將經驗值作為第二維維護有關忍耐度的背包的做法吧。。

f[s][n]代表有s個怪,此時經驗值為n,因為經驗值可能會溢出,所以將上限上調20點,即第二維下標最大為n+20。

初始賦值-1,對0怪0經驗即f[0][0]賦值忍耐度m,並且能得到狀態轉移方程f[i][j]=max(f[i-1][j-a[k]]-b[k]);

最後求解答案時將n到n+20這個經驗值區間內所有怪的個數的忍耐度求個最大值,就能得到答案了。

#include<cstdio>
#include
<cstring> int f[125][125],n,m,k,s,w[105],v[105],ans; int main(){ while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF){ for(int i=1;i<=k;i++) scanf("%d%d",&w[i],&v[i]); memset(f,-1,sizeof(f)); f[0][0]=m; for(int i=1;i<=k;i++)
for(int j=1;j<=s;j++) for(int r=w[i];r<=n+20;r++){ if(f[j][r]<f[j-1][r-w[i]]-v[i])f[j][r]=f[j-1][r-w[i]]-v[i]; } ans=-1; for(int i=1;i<=s;i++) for(int j=n;j<=n+20;j++) if(ans<f[i][j])ans=f[i][j]; printf(
"%d\n",ans); } }

HDU 2159