uva 12589

思路:

容易知道加向量的顺序是按向量斜率的大小顺序来的。由于数据不是很大,可以用背包解决!!

dp[i][j]:加入最大面积为i时,加入了j个向量。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<set>
 7 #include<vector>
 8 #define ll long long
 9 #define M 55
10 #define inf 1e10
11 #define mod 1000000007
12 using namespace std;
13 struct point
14 {
15     int x,y;
16     double k;
17     bool operator<(const point &a) const
18     {
19         return k>a.k;
20     }
21 }p[M];
22 int dp[M*M][M];
23 int main()
24 {
25     int i,j,m,t,ca=0,n,k;
26     scanf("%d",&t);
27     while(t--){
28         scanf("%d%d",&n,&k);
29         memset(dp,-1,sizeof(dp));
30         dp[0][0]=0;
31         for(i=0;i<n;i++){
32             scanf("%d%d",&p[i].x,&p[i].y);
33             if(p[i].x==0) p[i].k=inf;
34             else p[i].k=1.0*p[i].y/p[i].x;
35         }
36         sort(p,p+n);
37         int ans=0;
38         for(i=0;i<n;i++)
39         for(j=M*M-1;j>=0;j--){
40             for(int l=k-1;l>=0;l--)
41             if(dp[j][l]>=0){
42                 int tt=(p[i].y+2*j)*p[i].x+dp[j][l];
43                 dp[j+p[i].y][l+1]=max(dp[j+p[i].y][l+1],tt);
44             }
45         }
46         for(i=M*M-1;i>=0;i--) ans=max(ans,dp[i][k]);
47         printf("Case %d: %d
",++ca,ans);
48     }
49     return 0;
50 }
View Code