Help Jimmy POJ

来源:互联网 发布:制作歌曲伴奏软件 编辑:程序博客网 时间:2024/06/08 09:02

点击打开链接

两种解法

一:记忆化搜索 写法其实很多

       一个搜索题一般写法很多 理清思路 各种边界处理好就行 不要一会觉得这样行 过一会觉得那样好 反而搞乱了思路

#include <stdio.h>#include <cstring>#include <algorithm>using namespace std;#define N 0x3f3f3f3fstruct node{    int l;    int r;    int h;};node line[1010];int book[1010],left[1010],right[1010];int n,pos,hh,lim;bool cmp(node n1,node n2){    return n1.h>n2.h;}void dfs(int cur){    int i;    for(i=cur+1;i<=n+1;i++)    {        if(line[i].l<=line[cur].l&&line[cur].l<=line[i].r&&line[cur].h-line[i].h<=lim)        {            if(!book[i])            {                dfs(i);            }            if(i==n+1)            {                left[cur]=line[cur].h-line[i].h;            }            else            {                left[cur]=min(left[i]+line[cur].l-line[i].l,right[i]+line[i].r-line[cur].l)+(line[cur].h-line[i].h);            }            break;        }    }    for(i=cur+1;i<=n+1;i++)    {        if(line[i].l<=line[cur].r&&line[cur].r<=line[i].r&&line[cur].h-line[i].h<=lim)        {            if(!book[i])            {                dfs(i);            }            if(i==n+1)            {                right[cur]=line[cur].h-line[i].h;            }            else            {                right[cur]=min(left[i]+line[cur].r-line[i].l,right[i]+line[i].r-line[cur].r)+(line[cur].h-line[i].h);            }            break;        }    }    book[cur]=1;    return;}int main(){    int t,i,p,ans,tem;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d%d",&n,&pos,&hh,&lim);        for(i=1;i<=n;i++)        {            scanf("%d%d%d",&line[i].l,&line[i].r,&line[i].h);        }        sort(line+1,line+n+1,cmp);        line[n+1].l=-20000,line[n+1].r=20000,line[n+1].h=0;        memset(book,0,sizeof(book));        memset(left,0x3f,sizeof(left));        memset(right,0x3f,sizeof(right));        book[n+1]=1,left[n+1]=0,right[n+1]=0;        for(i=1;i<=n+1;i++)        {            if(line[i].l<=pos&&pos<=line[i].r)            {                p=i,ans=hh-line[i].h;                break;            }        }        if(p!=n+1)        {            dfs(p);            ans+=min(pos-line[p].l+left[p],line[p].r-pos+right[p]);        }        printf("%d\n",ans);    }    return 0;}

二:DP

#include <stdio.h>#include <cstring>#include <algorithm>#define N 99999999using namespace std;struct node{    int l;    int r;    int h;};struct node line[1001];int dp[1001][2];int n,sx,sy,lim;int cmp(node n1,node n2){    return n1.h>n2.h;}int main(){    int t,i,j,flagl,flagr,ans;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d%d",&n,&sx,&sy,&lim);        memset(dp,0,sizeof(int));        for(i=1;i<=n;i++)        {            scanf("%d%d%d",&line[i].l,&line[i].r,&line[i].h);            dp[i][0]=dp[i][1]=N;        }        line[0].l=sx,line[0].r=sx,line[0].h=sy;        line[n+1].l=-20000,line[n+1].r=20000,line[n+1].h=0;        sort(line,line+n+2,cmp);        dp[0][0]=dp[0][1]=0;        ans=N;        for(i=0;i<=n;i++)        {            flagl=1,flagr=1;            for(j=i+1;j<=n+1;j++)            {                if(flagl==0&&flagr==0||line[i].h-line[j].h>lim)                {                    break;                }                if(line[j].l<=line[i].l&&line[i].l<=line[j].r&&line[i].h!=line[j].h&&flagl==1)                {                    flagl=0;                    if(j==n+1)                    {                        ans=min(ans,dp[i][0]);                    }                    else                    {                        dp[j][0]=min(line[i].l-line[j].l+dp[i][0],dp[j][0]);                        dp[j][1]=min(line[j].r-line[i].l+dp[i][0],dp[j][1]);                    }                }                if(line[j].l<=line[i].r&&line[i].r<=line[j].r&&flagr==1)                {                    flagr=0;                    if(j==n+1)                    {                        ans=min(ans,dp[i][1]);                    }                    else                    {                        dp[j][0] = min(line[i].r-line[j].l+dp[i][1],dp[j][0]);                        dp[j][1] = min(line[j].r-line[i].r+dp[i][1],dp[j][1]);                    }                }            }            if(flagl==0)            {                if(line[i].h<=lim) dp[i][0]=line[i].h;                else dp[i][0]=N;            }            if(flagr==0)            {                if(line[i].h<=lim) dp[i][1]=line[i].h;                else dp[i][0]=N;            }        }        printf("%d\n",ans+sy);    }    return 0;}


原创粉丝点击