标准的完全背包问题,不过完全背包空间复杂度为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],×[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 }

浙公网安备 33010602011771号