題意:農夫約翰要購買**為t的物品,他有n種硬幣,每種硬幣的面額為vi,數量為ci,同時店主也只有這幾種面額的硬幣,但數量無限,問約翰總共要經手的硬幣數量(約翰買東西給店主的硬幣數量+店主找錢給約翰的硬幣數量=約翰經手的硬幣數量)(約翰是多重揹包,店主是完全揹包)
思路:我們用約翰所擁有的硬幣總額來做揹包容量是肯定不行的;
可以注意到,上界為w*w+m(w最大面額的紙幣),也就是24400元。(網上的證明)證明如下:
如果買家的付款數大於了w*w+m,即付硬幣的數目大於了w,根據鴿籠原理,至少有兩個的和對w取模的值相等,也就是說,這部分硬幣能夠用更少的w來代替。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define maxn 33000
#define inf 0x3f3f3f3f
#define lmid l,m,rt<<1
#define rmid m+1,r,rt<<1|1
#define ls rt<<1
#define rs rt<<1|1
#define mod 1000000007
#define i64 __int64
#define limit_ull 100000000000000000
using
namespace
std;
int dp1[25000];//約翰對不同金額所付的最少硬幣數量
int dp2[25000];//店長的
int v[105],w[105];
void wq(int w,int sum)
void dc(int v,int w,int sum)
else
for(int i=sum;i>=v*w;i--)
dp1[i]=min(dp1[i],dp1[i-v*w]+v);
}}int main()
for(int i=0;iscanf("%d",&v[i]);
sum=sum*sum+t+1;
memset(dp1,inf,sizeof(dp1));
memset(dp2,inf,sizeof(dp2));
dp1[0]=0,dp2[0]=0;
for(int i=0;iint res=inf;
for(int i=t;i<=sum;i++)
if(res==inf)
cout
<<"-1"
cout
0;}
POJ1276 多重揹包(01揹包 完全揹包)
多重揹包模板題,給定揹包容量 v 給定 n 種物品,每種物品的個數 n i 體積 v i 和重量 w i 已知,求揹包能裝下的物品的最大重量。對應本題就是,給定提款的金額cash,給定 n 種錢幣,每種錢幣的個數為 n i 面額 d i 已知,求能兌換的錢幣的最大值。本題中,體積和重量都等於面額。7...
01揹包 完全揹包 多重揹包
01揹包 zeroonepack 有n件物品和乙個容量為v的揹包,每種物品均只有一件。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。include include includeusing namespace std const int n 1000 10 int ...
01揹包 完全揹包 多重揹包
01揹包 zeroonepack 有n件物品和乙個容量為v的揹包。每種物品均只有一件 第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。完全揹包 completepack 有n種物品和乙個容量為v的揹包,每種物品都有無限件可用。第i種物品的費用是c i 價值是w i 求...