HDU 4216 Computational Geometry?【dp

Computational Geometry?

Time Limit : 6000/3000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other)
Total Submission(s) : 1   Accepted Submission(s) : 1
Font: Times New Roman | Verdana | Georgia
Font Size:  

Problem Description

Computational geometry is a branch of computer science devoted to the study of algorithms which can be stated in terms of geometry. It often comes up with charming shapes and ideas.
In this problem, our poor princess is trapped in a castle by some bad guys again, yeah, again. So, let's seize the chance to be a hero.
Right now, the beautiful princess is in the original point of a Cartesian coordinate system, for simplification, the castle is treated as a coordinate system, like a common computational geometry problem.
There is a bomb which can be exploded anytime, and it locates at (Xo, Yo) in the castle. To save the princess, we need design a route for her to leave away the bomb as far as possible. But she already has a plan written on her notebook, which contains some vectors, and she insists on escaping in the vectors’ direction one by one, that is, if she is in point(0, 0), and the vector is (X, Y), she will be in point(X, Y) if she escapes in this vector.
You get her notebook now, and find princess's plan is a not a good plan sometimes. Then you decide to help the princess to make some slight modification, you can change the order of those vectors, and/or reverse some vectors, that is, change vector (X, Y) to vector (-X, -Y).
We want to know the maximum distance to the bomb after modification.

Input

The first line contains a single integer T, indicating the number of test cases. Each test case begins with three integers N, Xo, Yo. Then N lines following, each line contains two integers, Xi and Yi, indicating a vector.

Technical Specification
1. 1 <= T <= 100
2. 1 <= N <= 100
3. -100 <= Xi, Yi <= 100
4. -10 000 <= Xo, Yo <= 10 000

Output

For each test case, output the case number first, then the distance rounded to three fractional digits.

Sample Input

3
1 1 1
1 1
2 2 3
-1 2
1 -2
3 3 0
2 3
3 2
1 -1

Sample Output

Case 1: 2.828
Case 2: 7.000
Case 3: 9.849

Author

iSea@WHU

Source

首届华中区程序设计邀请赛暨第十届武汉大学程序设计大赛

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<climits>
#include<string>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
#define rep(i,j,k)for(i=j;i<k;i++)
#define per(i,j,k)for(i=j;i>k;i++)
#define MS(x,y)memset(x,y,sizeof(x))
const int INF= 0x7FFFFFFF;
typedef  long long  LL;
#define D 10000
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
int num[105][2];
int dp[2][20005][2];
int T,n,x,y;
double dis(int a,int b)
{
    double c=(double)a,d=(double)b;
    return sqrt((c-x)*(c-x)+(d-y)*(d-y));
}
int main()
{
    scanf("%d",&T);
    for(int cas=1; cas<=T; ++cas)
    {
        scanf("%d%d%d",&n,&x,&y);
        x+=D;
        y+=D;
        for(int i=1; i<=n; ++i)
        {
            scanf("%d%d",&num[i][0],&num[i][1]);
        }
        memset(dp,-1,sizeof(dp));
        dp[0][D][0]=dp[0][D][1]=D;
        for(int i=1; i<=n; ++i)
        {
            for(int j=0; j<=20000; ++j)
                for(int k=0; k<2; ++k)
                {
                    if(dp[(i-1)&1][j][k]!=-1)
                    {

                        if(dp[i&1][j+num[i][1]][0]==-1||dp[i&1][j+num[i][1]][0]>dp[(i-1)&1][j][k]+num[i][0])
                            dp[i&1][j+num[i][1]][0]=dp[(i-1)&1][j][k]+num[i][0];
                        if(dp[i&1][j-num[i][1]][0]==-1||dp[i&1][j-num[i][1]][0]>dp[(i-1)&1][j][k]-num[i][0])
                            dp[i&1][j-num[i][1]][0]=dp[(i-1)&1][j][k]-num[i][0];
                        if(dp[i&1][j+num[i][1]][1]==-1||dp[i&1][j+num[i][1]][1]<dp[(i-1)&1][j][k]+num[i][0])
                            dp[i&1][j+num[i][1]][1]=dp[(i-1)&1][j][k]+num[i][0];
                        if(dp[i&1][j-num[i][1]][1]==-1||dp[i&1][j-num[i][1]][1]<dp[(i-1)&1][j][k]-num[i][0])
                            dp[i&1][j-num[i][1]][1]=dp[(i-1)&1][j][k]-num[i][0];
                    }
                }
        }
        double dist=0.0;
        for(int i=0; i<=20000; ++i)
            for(int j=0; j<2; ++j)
                if(dp[n&1][i][j]!=-1)
                    dist=max(dist,dis(dp[n&1][i][j],i));
        printf("Case %d: %.3f\n",cas,dist);
    }
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值