動態規劃總結
阿新 • • 發佈:2018-12-09
一.揹包問題:
揹包的初始化相關問題:
1.最大價值且恰好裝滿:dp[0]=0 其他負無窮
2.最小价值且恰好裝滿:dp[0]=0 其他正無窮
3.不恰好裝滿:都為0
揹包模板:
#include<cstdio> int main() { //W 總重量 n 物品個數 v[i]價值 W[i] 重量 //一維 int dp[MAX],v[MAX],w[MAX]; //01揹包問題 for(int i=1;i<=n;i++) for(int j=W;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+v[i]); //完全揹包問題 for(int i=1;i<=n;i++) for(int j=w[i];j<=W;j++) dp[j]=max(dp[j],dp[j-w[i]]+v[i]); //多重揹包 n[i] 個數 void zero(int cost,int val) { for(int i=W;i>=cost;i--) dp[i]=max(dp[i],dp[i-cost])+val; } void comple(int cost,int val) { for(int i=cost;i<=W;i++) dp[i]=max(dp[i],dp[i-cost]+val); } void muti(int cost,int val,int num) { if(cost*num>=W)//num個裡面可以湊夠W { comple(cost,val); } else{//否則二進位制優化找01揹包 int k=1; while(k<num) { zero(k*cost,k*val); num-=k; k*=2; } zero(num*cost,num*val); } } for(int i=1;i<=n;i++) muti(w[i],v[i],n[i]); //分組揹包 for(int i=1;i<=k;i++)//k為組數 { for(int j=W;j>=0;j--)//此時每組只能選一個 { for(int t=1;t<=n;t++)//每組個數 { dp[i][j]=max(dp[i][j],dp[i][j-w[t]]+v[t]);//n為每組個數 } } } return 0; }