UVALive 6042 Bee Tower (dp)

题目:传送门

思路:题目要求能从地面开始跳到最高的塔,在满足这个条件的前提下移动塔,并求出移动塔的最小花费。那么先找到最高的塔,然后向左右两边遍历,看看是否能到达地面,然后用dp求解最小移动花费。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack> 
#include<vector>
#include<algorithm>
#define N 55
#define INF 10000000
#define LL long long
#define EPS 1e-8
using namespace std;

struct tower{
    int p,h;
}tow[N];

int n,W,H;
int dp[N][605];

int cmp(tower a,tower b)
{
    return a.p<b.p;
}

int main()
{
    int T;
    int maxh;
    scanf("%d",&T);
    for(int t=1;t<=T;t++)
    {
        scanf("%d%d%d",&n,&H,&W);
        maxh=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&tow[i].p,&tow[i].h);
            maxh=max(maxh,tow[i].h);
        }
        int l,r;
        bool flag;
        int ans=INF;
        for(int i=1;i<=n;i++)
        {
            if(maxh<=H)
            {
                ans=0;
                break;
            }
            if(tow[i].h!=maxh) continue;
            l=i-1;
            flag=true;
            while(l>0)
            {
                if(tow[l+1].h-tow[l].h>H)
                {
                    flag=false;
                    break;
                }
                if(tow[l].h<=H) break;
                l--;
            }
            //cout<<l<<endl;
            if(flag&&l>0)
            {
                memset(dp,0,sizeof(dp));
                for(int j=1;i-j>=l;j++)
                {
                    for(int p=tow[i].p-j;p>=max(0,tow[i].p-W*j);p--)
                    {
                        int minw=INF;
                        for(int pl=max(p+1,tow[i].p-W*(j-1));pl<=min(p+W,tow[i].p-j+1);pl++)
                        {
                            minw=min(minw,dp[j-1][pl]);
                        }
                        dp[j][p]=abs(tow[i-j].p-p)*tow[i-j].h+minw;
                        if(i-j==l) ans=min(dp[j][p],ans);
                    }
                }
            }
            r=i+1;
            flag=true;
            while(r<=n)
            {
                if(tow[r-1].h-tow[r].h>H)
                {
                    flag=false;
                    break;
                }
                if(tow[r].h<=H) break;
                r++;
            }
            if(flag&&r<=n)
            {
                memset(dp,0,sizeof(dp));
                for(int j=1;j+i<=r;j++)
                {
                    for(int p=tow[i].p+j;p<=tow[i].p+W*j;p++)
                    {
                        int minw=INF;
                        for(int pl=min(p-1,tow[i].p+W*(j-1));pl>=max(p-W,tow[i].p+j-1);pl--)
                        {
                            minw=min(minw,dp[j-1][pl]);
                        }
                        dp[j][p]=abs(tow[i+j].p-p)*tow[i+j].h+minw;
                        if(j+i==r) ans=min(ans,dp[j][p]);
                    }
                }
            }
        }
        if(ans==INF) ans=-1;
        printf("Case #%d: %d\n",t,ans);
    }
}

猜你喜欢

转载自blog.csdn.net/cyf199775/article/details/77600359
Bee
今日推荐