http://acm.hdu.edu.cn/showproblem.php?pid=1114&&完全背包

题意:硬币的数量不限制,让储蓄罐装满时得到的最少价值。

思路:先将完全背包转化成多重背包,再转化成0-1背包来解,不过这里要进行二进制优化,因为这里要保证储蓄罐要装满,所以需要先把容量为0时,价值赋为0,因为让求最小价值,因此需要把大于0的容量都赋为无穷大,如果让求的是装满时的最大价值则要把大于0的容量都赋为无穷小。。。

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 10000;
int dp[10001];
int w[350005];
int v[350005];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
	  int p,q;
	  cin>>p>>q;
	  p=q-p;
	  for(int i=0;i<10001;++i)
	  dp[i]=0xfffff;
	  dp[0]=0;
	  int n;
	  cin>>n;
	  int tot=0;
	  for(int i=0;i!=n;++i)
	  {
		  int a,b;
		  cin>>a>>b;
		  int k=p/b;
		  int t=1;
		  while(2*t<k+1)
		  {
			  w[tot]=t*b;
			  v[tot++]=t*a;
			  t=2*t;
		  }
		  w[tot]=(k+1-t)*b;
		  v[tot++]=(k+1-t)*a;
       }
	  for(int i=0;i<tot;++i)
		 {  
			 if(w[i]>p) continue;
			 for(int j=p;j>=w[i];--j)
			   dp[j]=min(dp[j-w[i]]+v[i],dp[j]);
		}
	  if(dp[p]<0xfffff) cout<<"The minimum amount of money in the piggy-bank is "<<dp[p]<<"."<<endl;
	  else cout<<"This is impossible."<<endl;
		}return 0;
}

完全背包:

#include<iostream>
#include<string.h>
#include<algorithm>
#define N 10001
using namespace std;
int dp[N];
int w[501],v[501];
int main()
{
   int t;
   cin>>t;
   while(t--)
   {
       int p,q;
       cin>>p>>q;
       p=q-p;
       int n;
       cin>>n;
       for(int i=0;i<N;++i)
           dp[i]=0xfffff;
       dp[0]=0;
       for(int i=0;i!=n;++i)
          cin>>v[i]>>w[i];
         for(int i=0;i<n;++i)
             { 
                 if(w[i]>p) continue;
                 for(int j=w[i];j<=p;++j)
                {
                  dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
                }
            }
             
         if(dp[p]<0xfffff) cout<<"The minimum amount of money in the piggy-bank is "<<dp[p]<<"."<<endl;
      else cout<<"This is impossible."<<endl;
   }return 0;
}



你可能感兴趣的:(http://acm.hdu.edu.cn/showproblem.php?pid=1114&&完全背包)