uva12589

题目大意:给n(n<=50)个向量(xi,yi) (0<=xi<=yi<=50),选出其中k(1<=k<=n)个,从(0,0)点开始,依次首尾相连,求此k个向量与x正半轴围成的最大面积的两倍并输出。

初步想法,向量都在第一象限,所以最优解一定是选中k个排成上凸曲线。故第一步是按照向量斜率排序!

然后就是迭代dp了。

先看看暴力方程dp[i][j][y]=max(dp[i][j][y],dp[o][j-1][y-li[i].y]+f(li[i].x,li[i].y,y)) (对于任意的i>o>=j)这个时候需要枚举o,效率是很不乐观的。

优化:假设dp[i][*][*]都已经求出来了。

那么dp[i+1][j][y]=max(dp[i][j][y],dp[i][j-1][y-li[i+1].y]+f(li[i+1].x,li[i+1].y,y)),这样i推出i+1就是O(1)的效率了,初始状态就是dp[x][0][0]=0。

再加上一点剪枝,这样就是很好的solution了。

再看看样例,有T<=110个case,所以不能每次循环都memset(dp,0,sizeof(dp))一遍,加访问标记。(建议ACMer新手每次一定要记得看看样例有多少组)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 int dp[51][51][2501];
 8 int stamps[51][51][2501];
 9 struct line{
10     int x,y;
11     friend bool operator<(line S,line T){
12         return S.y*T.x > T.y*S.x;
13     }
14 }li[55];
15 int main()
16 {
17     int cases; cin>>cases;
18     int n,k;
19     for(int cas=1;cas<=cases;cas++){
20         scanf("%d%d",&n,&k);
21         for(int i=1;i<=n;i++)
22             scanf("%d%d",&li[i].x,&li[i].y);
23         for(int i=0;i<=n;i++)
24             dp[i][0][0]=0,stamps[i][0][0]=cas;
25         sort(li+1,li+n+1);
26         int t;
27         for(int i=1;i<=n;i++){
28             int maxj=min(i,k),minj=max(1,k-(n-i+1));
29             for(int j=minj;j<=maxj;j++){
30                 for(int y=2500;y>=0;y--){
31                     dp[i][j][y]=0;
32                     if(i>j && stamps[i-1][j][y]>=cas) dp[i][j][y]=dp[i-1][j][y], stamps[i][j][y]=cas;
33                     if((y-li[i].y)>=0 && stamps[i-1][j-1][y-li[i].y]>=cas)
34                         dp[i][j][y] = max(dp[i][j][y],dp[i-1][j-1][y-li[i].y]+(y+y-li[i].y)*li[i].x), stamps[i][j][y]=cas;
35                 }
36             }
37         }
38         int ans=0;
39         for(int y=2500;y>=0;y--)
40         if(stamps[n][k][y]>=cas) ans=max(ans,dp[n][k][y]);
41         printf("Case %d: %d\n",cas,ans);
42     }
43     return 0;
44 }
View Code

 

posted on 2013-09-26 22:32  男神发量  阅读(371)  评论(0编辑  收藏  举报