poj 1276

Posted 一个_小菜鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 1276相关的知识,希望对你有一定的参考价值。

一道DP的题目,还是一道多重背包的题目,第一次接触。

题意:有现今cash,和n种钱币,每种钱币有ni个,价值为di,求各种钱币组成的不超过cash的最大钱数

思路:可以转换为0/1背包和完全背包来做。

 

  1 Memory: 648K		Time: 16MS
  2 Language: C++		Result: Accepted
  3 #include <stdio.h>
  4 #include <iostream>
  5 #include <string.h>
  6 
  7 int cash,n;
  8 
  9 int num[100005],price[100005];
 10 
 11 bool us[100005];
 12 int user[100005];
 13 
 14 void calc()
 15 {
 16     memset(us,false,sizeof(us));
 17     us[0]=true;
 18     for(int i=0;i<n;i++)
 19     {
 20         memset(user,0,sizeof(user));
 21         for(int j=price[i];j<=cash;j++)
 22             if(us[j-price[i]]&&!us[j]&&user[j-price[i]]<num[i])   //这是这个程序的重点,为什么j++,而不是j成倍的增加price倍,其实,这通过us[j-price[i]]和!us[j]就限制了,它只可以增加price倍,当增加的不是price的倍数时,us[j-price[i]]是假的,当j为2倍时,由于之前us[j]也就是us[price]被赋值为了ture,所以这个if语句成立。以此类推
 23         {
 24             us[j]=true;
 25             user[j]=user[j-price[i]]+1;
 26         }
 27     }
 28 }
 29 
 30 int main()
 31 {
 32     while(scanf("%d%d",&cash,&n)!=EOF)
 33     {
 34         for(int i=0;i<n;i++)
 35             scanf("%d%d",&num[i],&price[i]);
 36         calc();
 37         for(int i=cash;i>=0;i--)
 38             if(us[i])
 39             {
 40                 printf("%d\n",i);
 41                 break;
 42             }
 43     }
 44     return 0;
 45 }

以上是关于poj 1276的主要内容,如果未能解决你的问题,请参考以下文章

POJ1276(多重背包)

poj1276

POJ1276 多重背包(01背包 完全背包)

POJ - 1276 Cash Machine(多重背包)

poj 1276

poj 1276(多重背包+最接近)