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的主要内容,如果未能解决你的问题,请参考以下文章