HDU4562 守護雅典娜(DP)

守護雅典娜

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 609    Accepted Submission(s): 179

Problem Description
許多塔防遊戲都是以經典的“守護雅典娜”爲原型的。玩家需要建立各種防禦工具來阻止怪物接近我們的女神——雅典娜。

這裏,我們可以建造的防禦工具只有標準圓形狀的防禦牆,建立在雅典娜與怪物出生點之間的防禦牆數目越多,勝利的希望就越大。這裏,將問題簡化到一個二維座標系裏,並且假設雅典娜的座標爲原點(0, 0),怪物出生點的座標爲(X, Y)。有N個給定圓心座標與半徑的防禦牆可以供玩家選擇建立,但要保證所有的圓都不發生相切或相交的情況。注意這些雅典娜位置與怪物出生點位置也不能在牆壁的邊緣,即表示防禦牆的圓上。點的面積與牆的厚度都很小,可以忽略不計。

記住,在遊戲開始之後,怪物可以沿着任何軌跡,選擇突破最少的圓形防禦牆來到雅典娜的身邊,而一個防禦牆一旦被突破,它就會失去保護作用。所以,你的方案必須足夠優秀。爲了守護女神,快去找出最優的建設方案吧!
 

Input

輸入第一行爲T,表示有T組測試數據。
每組數據以三個整數N,X,Y開始,接下去的N行每行包括三個整數Xi,Yi,Ri,表示一個可以選擇的圓心爲(Xi, Yi)半徑爲Ri的防禦牆。

[Technical Specification]

1. 1 <= T <= 100
2. 1 <= N <= 1000
3. 1 <= Ri <= 10 000
4. -10 000 <= X, Y, Xi, Yi <= 10 000,座標不會相同

 Output

對每組數據,先輸出爲第幾組數據,然後輸出能夠間隔在雅典娜與怪物出生點之間最多的防禦牆數目。

 Sample Input

3 1 5 5 1 0 2 1 5 5 1 0 9 3 5 5 1 0 2 4 5 2 2 0 6
 

Sample Output

Case 1: 1 Case 2: 0 Case 3: 2

 Source

 Recommend

liuyiding
 


#include <iostream>
#include <algorithm>
#include <queue>
#include <math.h>
using namespace std;

const int MAXN=1010;
struct Node
{
    int x,y;
    int r;
};
bool cmp(Node a,Node b)
{
    return a.r<b.r;
}
int dis2(Node a,Node b)
{
    return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
Node node[MAXN];
Node node1[MAXN];
Node node2[MAXN];
int dp1[MAXN];
int dp2[MAXN];
int main()
{
    int T;
    int n;
    int iCase=0;
    Node st;
    st.x=0;st.y=0;
    Node ed;
    scanf("%d",&T);
    while(T--)
    {
        iCase++;
        printf("Case %d: ",iCase);
        scanf("%d",&n);
        scanf("%d%d",&ed.x,&ed.y);
        int t1=0;
        int t2=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].r);
            int d1=dis2(st,node[i]);
            int d2=dis2(ed,node[i]);
            if(d1==node[i].r*node[i].r||d2==node[i].r*node[i].r)
                continue;
            if(d1<node[i].r*node[i].r&&d2<node[i].r*node[i].r)continue;
            if(d1>node[i].r*node[i].r&&d2>node[i].r*node[i].r)continue;
            if(d1<node[i].r*node[i].r)
            {
                node1[t1++]=node[i];
            }
            else node2[t2++]=node[i];
        }
        sort(node1,node1+t1,cmp);
        sort(node2,node2+t2,cmp);
        int ans1=0,ans2=0;
        for(int i=0;i<t1;i++)
        {
            dp1[i]=1;
            for(int j=0;j<i;j++)
            {
                int d=dis2(node1[i],node1[j]);
                if(node1[i].r>node1[j].r && d<(node1[i].r-node1[j].r)*(node1[i].r-node1[j].r))
                    dp1[i]=max(dp1[i],dp1[j]+1);
            }
            ans1=max(ans1,dp1[i]);
        }
        for(int i=0;i<t2;i++)
        {
            dp2[i]=1;
            for(int j=0;j<i;j++)
            {
                int d=dis2(node2[i],node2[j]);
                if( node2[i].r>node2[j].r && d<(node2[i].r-node2[j].r)*(node2[i].r-node2[j].r))
                    dp2[i]=max(dp2[i],dp2[j]+1);
            }
            ans2=max(ans2,dp2[i]);
        }
        int ans=max(ans1,ans2);
        for(int i=0;i<t1;i++)
            for(int j=0;j<t2;j++)
            {
                int d1=dis2(node1[i],node2[j]);
                if(d1>(node1[i].r+node2[j].r)*(node1[i].r+node2[j].r))
                    ans=max(ans,dp1[i]+dp2[j]);
            }
        printf("%d\n",ans);
    }

    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章