hdu 2059 龟兔赛跑 动规问题

来源:互联网 发布:在线排课软件 编辑:程序博客网 时间:2024/06/07 03:11

首先 这个题目我并没有用动规的思想来做,自己写了个程序 手动模拟加油与不加油的情况,并在每次取得较小值,

在样本数据中演示毫无压力,但是提交的时候WA了 , 仔细看了题干条件  猜了一些测试数据,还是没错,所以不知道哪个地方错了

还麻烦能找到特殊数据证明我这个程序错误的大大多多指教,谢谢了!

源代码如下:


#include<stdio.h>
#define NUM 100
int P[NUM+10];


double calculate(int n,int c,int t,int vt1,int vt2,int l)
{
int i,cc=c;
double time=0.0;
for(i=0;i<n;i++)
{
if(i==0)
{
if(P[i]<=cc)
{
time+=(double)P[i]/vt1;
cc-=P[i];
}
else
{
time+=(double)cc/vt1+(double)(P[i]-cc)/vt2;
cc=0;
}
}
else
{
int x1=P[i]-P[i-1],x2=P[i]-P[i-1],cc1=cc,cc2=cc;
double time1=0.0,time2=0.0;
cc1=c;
time1+=t;
if(x1<=cc1)
{
time1+=(double)x1/vt1;
cc1-=x1;
}
else
{
time1+=(double)cc1/vt1+(double)(x1-cc1)/vt2;
cc1=0;
}


if(x2<=cc2)
{
time2+=(double)x2/vt1;
cc2-=x2;
}
else
{
time2+=(double)cc2/vt1+(double)(x2-cc2)/vt2;
cc2=0;
}


if(time1<time2)
{
time+=time1;
cc=cc1;
}
else
{
time+=time2;
cc=cc2;
}
}

}
if(i==n)
{
int x1=l-P[n-1],x2=l-P[n-1],cc1=cc,cc2=cc;
double time1=0.0,time2=0.0;
cc1=c;
time1+=t;
if(x1<=cc1)
{
time1+=(double)x1/vt1;
cc1-=x1;
}
else
{
time1+=(double)cc1/vt1+(double)(x1-cc1)/vt2;
cc1=0;
}


if(x2<=cc2)
{
time2+=(double)x2/vt1;
cc2-=x2;
}
else
{
time2+=(double)cc2/vt1+(double)(x2-cc2)/vt2;
cc2=0;
}


if(time1<time2)
time+=time1;
else
time+=time2;


return time;
}
}
int main()
{
int L,N,C,T,VR,VT1,VT2;
while(scanf("%d%d%d%d%d%d%d",&L,&N,&C,&T,&VR,&VT1,&VT2)!=EOF)
{
int i;
for(i=0;i<N;i++)
scanf("%d",P+i);
double t1=(double)L/VR;
double t2=calculate(N,C,T,VT1,VT2,L);
if(t1>t2)
printf("What a pity rabbit!\n");
else
printf("Good job,rabbit!\n");
}
return 0;
}


既然这个在oj上提交显示错误,那没办法了,只能选择用动规的思想来做了

f[n+2]表示每个加油站所用的最小的时间,起点和终点也算成两个加油站,在i每次到了一个点的时候,

取j从0开始到i-1的站,在每个站计算当前j到i加油站的时间,然后取值f[i]=min(f[i],f[j]+time)

子问题是f[i]肯定包含了f[j]的最小时间,用剪贴思想即可想到

该程序从表面上看是在每个点都加了油,但是其实是这样的:

i=4 j=1时,从1加油站开始加满油 跑到第四个加油站了,这个中间包含了在2 3 加油站有没有加油的情况,在每次读表的时候都取到了当前的最小值

这里面就包含了在各个站加或不加的情况了

源代码如下:


#include<stdio.h>
#define NUM 100
#define INT_MAX 999999999
int p[NUM+10];
double f[NUM+10];


int main()
{
int l,n,c,t,vr,vt1,vt2;
while(scanf("%d%d%d%d%d%d%d",&l,&n,&c,&t,&vr,&vt1,&vt2)!=EOF)
{
int i,j;
double time1;
p[0]=0;
for(i=1;i<=n;i++)
scanf("%d",p+i);
p[n+1]=l;

f[0]=0;
for(i=1;i<=n+1;i++)
f[i]=INT_MAX;


for(i=1;i<=n+1;i++)
for(j=0;j<i;j++)     //动规核心算法
{
int k=p[i]-p[j];
if(k>c)
time1=(double)c/vt1+(double)(k-c)/vt2;
else
time1=(double)k/vt1;


if(j>0)
time1+=t;


if(f[i]>f[j]+time1)
f[i]=f[j]+time1;
}


if(f[n+1]>(double)l/vr)
printf("Good job,rabbit!\n");
else
printf("What a pity rabbit!\n");
}


return 0;
}

原创粉丝点击