标准的完全背包问题,不过完全背包空间复杂度为O(vn),这道题给出的v和n都是10000,直接开内存肯定MLE,所以新接触了一个名词:滚动数组,把不需要的空间重复利用就行了,因为dp只需要知道前一个n的所有值,不需要开10000*10000的空间,只需要2*10000就行了。下面贴出代码,以作纪念。

View Code
 1 /*{
 2 ID:jzy3209981
 3 PROG:inflate
 4 LANG:C++
 5 }*/
 6 #include<stdio.h>
 7 #include<iostream>
 8 #include<string.h>
 9 #include<math.h>
10 using namespace std;
11 
12 int times[10005];
13 int score[10005];
14 int sum;
15 int kind;
16 int dp[2][10005];
17 int max(int a,int b)
18 {
19     return a>b?a:b;
20 }
21 int main()
22 {
23     freopen ("inflate.in","r",stdin);
24     freopen ("inflate.out","w",stdout);    
25     int i,j;
26     scanf("%d%d",&sum,&kind);
27     for(i=0;i<kind;i++)
28         scanf("%d%d",&score[i],&times[i]);
29     for(j=0;j<=sum;j++)
30         dp[0][j]=j/times[0]*score[0];
31     for(i=1;i<kind;i++)
32     {        
33         for(j=0;j<=sum;j++)
34         {
35             if(j<times[i])
36                 dp[i%2][j]=dp[(i-1)%2][j];
37             else
38                 dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-times[i]]+score[i]);
39         }
40     }
41     printf("%d\n",dp[(i-1)%2][sum]);    
42     return 0;
43 }

 

posted on 2012-08-13 15:36  醉春雨  阅读(146)  评论(0)    收藏  举报