【動態規劃——盜版無限揹包(有個數限制)】coin——金幣
阿新 • • 發佈:2019-02-06
題目講解:
用一個數組f[i]表示i的價格是否能達到
f[0]=1,表示價格為0可以到達,賦初值
後用s[i][j]表示到達i的價格用的第j個錢幾個
用無限揹包的方法加一句判斷s[i][j]<j所能用的最大個數
(無限揹包不會的話看程式後的講解)
#include<cstdio> #include<cstring> int n,m; int a[201]; int maxa[201]; int s[200001][201]; int f[200001]; int main() { // freopen("coin.in","r",stdin); // freopen("coin.out","w",stdout); while(1) { memset(s,0,sizeof(s)); memset(f,0,sizeof(f)); scanf("%d %d",&n,&m); if(n==0&&m==0) { return 0; } for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=n;i++) { scanf("%d",&maxa[i]); } f[0]=1; for(int i=1;i<=n;i++) { for(int j=0;j<=m;j++) { if(f[j]==1&&f[j+a[i]]==0&&s[j][i]<maxa[i]) { f[j+a[i]]=1; s[j+a[i]][i]=s[j][i]+1; } } } int ans=0; for(int i=1;i<=m;i++) { if(f[i]==1) { ans++; } } printf("%d\n",ans); } return 0; }
無限揹包講解:
一個物品可以放很多次
所以先前更新的狀態要求影響後面更新的狀態
01揹包要求是從最大值向後掃以保證每個物品只用一次
所以每個物品可以用多次,從前往後掃即可
例子(f[i]表示與上程式中一樣):
假設物品質量4
容量10
01:從10往前掃,掃到f[0]=1,然後更新f[0+4]=1
無限:從0往後掃,首先掃到f[0]=1,更新f[0+4]=1
再往後掃,再次掃到f[4],更新f[4+4]=1,這樣類推即
可實現無限放置同一件物品