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

 

你可能感兴趣的:(uva)