HDU 4216 Computational Geometry?

                                   Computational Geometry?

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 716    Accepted Submission(s): 250


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

题目大意:有一个炸弹和一个公主,给出炸弹的坐标,公主在原点,公主有几个可以走的方案,给出每个向量,这个向量表示公主会朝这个方向走这个向量的长度,改变走的向量的顺序或者是将向量反转,问最后公主离炸弹最远的距离

其实我们不一定非要从公主入手,我们可以让炸弹走,这样和公主自己走是等效的,而且仔细想想可以知道顺序其实是无关的,那这样就可以用dp来解决这道题

#include <bits/stdc++.h>
using namespace std;
const int inf=1e8;
const int dis=22500;
const int maxn=45010;
int dp_max[110][maxn];
int dp_min[110][maxn];
int main()
{
    int test;
    scanf("%d",&test);
    for(int cas=1;cas<=test;cas++)
    {
        int n;
        int x0,y0;
        scanf("%d%d%d",&n,&x0,&y0);
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=45000;j++)
            {
                dp_max[i][j]=-inf;
                dp_min[i][j]=inf;
            }
        }
        dp_max[0][x0+dis]=dp_min[0][x0+dis]=y0;
        for(int i=1;i<=n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            for(int j=-22000;j<=22000;j++)
            {
                if(dp_max[i-1][j+dis-x]!=-inf)
                {
                    dp_max[i][j+dis]=max(dp_max[i][j+dis],dp_max[i-1][j+dis-x]+y);
                }
                if(dp_max[i-1][j+dis+x]!=-inf)
                {
                    dp_max[i][j+dis]=max(dp_max[i][j+dis],dp_max[i-1][j+dis+x]-y);
                }
                if(dp_min[i-1][j+dis-x]!=inf)
                {
                    dp_min[i][j+dis]=min(dp_min[i][j+dis],dp_min[i-1][j+dis-x]+y);
                }
                if(dp_min[i-1][j+dis+x]!=inf)
                {
                    dp_min[i][j+dis]=min(dp_min[i][j+dis],dp_min[i-1][j+dis+x]-y);
                }
            }
        }
        double ans=0;
        for(int j=-22000;j<=22000;j++)
        {
            if(dp_max[n][j+dis]!=-inf)
            {
                ans=max(ans,(double)(j*j+dp_max[n][j+dis]*dp_max[n][j+dis]));
            }
            /////////////////
            if(dp_min[n][j+dis]!=inf)
            {
                ans=max(ans,(double)(j*j+dp_min[n][j+dis]*dp_min[n][j+dis]));
            }
        }
        printf("Case %d: %.3lf\n",cas,sqrt(ans));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37943488/article/details/81184442