ZOJ 3956 Course Selection System

meaning of the title

  There are n lessons to choose from, each lesson has two values ​​Hi and Ci, if the student chooses m lessons (x1,x2,....,xm), its comfort value is defined as:

  //There is no formula here ((lll¬ω¬)), because I can't save that picture ≧ ﹏ ≦, see the original title~

analyze

  At that time, I was very confused by this formula. After thinking about several greedy discoveries on the field, I could find counterexamples. After the end, I heard from the seniors that it was a backpack. . . Confused.

  We are looking at this question... We found that Ci is much smaller than Hi... Here is a hint o(* ̄▽ ̄*)o

  When we look at the formula again, we can find that when C is constant, the larger H is, the greater the comfort value is. And for each class we have only two decisions, to choose or not to choose. Then we can turn this problem into a knapsack~

  We define f[i][j] = the maximum H value in this state. We follow the knapsack routine, take the class as a stage, and define C as a state.

  Then the transfer is also obvious

  f[i][j]=max(f[i-1][j],f[i-1][j-C[i]]+H[i])

  But wait, this submission will not be AC ​​but a Segmentation Fault, which is very confusing, and it is wrong to change it. Then I checked the solution and found that I used a rolling array. What the hell is ZOJ! ! Shouldn't this situation prompt MLE or something (fog~

  Then change the scrolling array, the code is shorter.

  

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 typedef long long LL;
 8 const int maxn=500+10;
 9 int T,n,M;
10 LL C[maxn],H[maxn];
11 LL f[50000+10];
12 
13 int main(){
14     scanf("%d",&T);
15     for(int t=1;t<=T;t++){
16         M=0;
17         scanf("%d",&n);
18         for(int i=1;i<=n;i++){
19             scanf("%d%d",&H[i],&C[i]);
20             M+=C[i];
21         }
22         memset(f,0,sizeof(f));
23         for(int i=1;i<=n;i++){
24             for(int j=M;j>=C[i];j--){
25                 f[j]=max(f[j],f[j-C[i]]+H[i]);
26             }
27         }
28         LL ans=0;
29         for(int i=0;i<=M;i++)
30             ans=max(ans,f[i]*f[i]-f[i]*i-i*i);
31         printf("%lld\n",ans);
32     }
33 return 0;
34 }
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324777083&siteId=291194637