您的位置:首页 > 其它

UVALive 6042 Bee Tower (dp)

2017-08-26 12:01 246 查看
题目:传送门

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

int n,W,H;
int dp
[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;

ab11
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: