hdu2059: http://acm.hdu.edu.cn/showproblem.php?pid=2059
题意:乌龟骑着充满电的电动车从起点出发,途中有n个充电站,离起点的距离为p[i],电动车每次充电后电动时间为t,乌龟电动速度为v1,脚踩电动车速度为v2,兔子恒速为vr,问龟兔输赢。
解法:dp:优化前方程:dp[i][j]表示乌龟上次充电的站点为j,为从起点到i站时间,dp[i][j]=min(dp[i][j],x+dp[j][k]),dp[j][k]为在站点k充电后到j,从起点到j站花费的最短时间(最短因为已经算过了),x为从j站到i站花费的时间,需要3个for。可优化为一维,dp[i]表示从某个站点充电后到达i所用的最短时间,则dp[i]=min(dp[i],dp[j]+x),只需2个for。
优化前code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int inf=1<<30;
double dp[150][150];
int p[150];
int min(int a,int b)
{
if(a<b)
return a;
else
return b;
}
int main()
{
int l,n,c,t,vr,v1,v2;
double x,mm;
while(scanf("%d",&l)!=EOF)
{
scanf("%d%d%d",&n,&c,&t);
scanf("%d%d%d",&vr,&v1,&v2);
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
for(int i=0;i<=n+1;i++)
for(int j=0;j<=n+1;j++)
dp[i][j]=inf;
p[n+1]=l;p[0]=0;dp[0][0]=0;
for(int i=1;i<=n+1;i++)
{
if(p[i]<c)dp[i][0]=1.0*p[i]/v1;
else dp[i][0]=1.0*c/v1+1.0*(p[i]-c)/v2;
}
for(int i=1;i<=n+1;i++) //枚举末站点
{
for(int j=0;j<i;j++) //枚举初站点
{
if(p[i]-p[j]<c)
x=t+1.0*(p[i]-p[j])/v1;
else
x=t+1.0*c/v1+1.0*(p[i]-p[j]-c)/v2; //求出从j到i的时间
for(int k=0;k<j;k++)
dp[i][j]=min(dp[i][j],x+dp[j][k]);
}
}
mm=dp[n+1][0];
for(int i=1;i<=n+1;i++)
if(dp[n+1][i]<mm)
mm=dp[n+1][i];
if(mm<1.0*l/vr)
printf("What a pity rabbit!\n");
else
printf("Good job,rabbit!\n");
}
}
优化后code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
double dp[150];
int p[150];
int min(int a,int b)
{
if(a<b)
return a;
else
return b;
}
int main()
{
int l,n,c,t,vr,v1,v2;
double x;
while(scanf("%d",&l)!=EOF)
{
scanf("%d%d%d",&n,&c,&t);
scanf("%d%d%d",&vr,&v1,&v2);
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
p[n+1]=l;p[0]=0;dp[0]=0;
for(int i=1;i<=n+1;i++)
{
if(p[i]<c)dp[i]=1.0*p[i]/v1;
else dp[i]=1.0*c/v1+1.0*(p[i]-c)/v2;
}
for(int i=1;i<=n+1;i++)
{
for(int j=0;j<i;j++)
{
if(p[i]-p[j]<c)
x=t+1.0*(p[i]-p[j])/v1;
else
x=t+1.0*c/v1+1.0*(p[i]-p[j]-c)/v2;
dp[i]=min(dp[i],dp[j]+x);
}
}
if(dp[n+1]<1.0*l/vr)
printf("What a pity rabbit!\n");
else
printf("Good job,rabbit!\n");
}
}
/*input:
100
3 20 5
5 8 2
10 40 60
100
3 60 5
5 8 2
10 40 60
output:
Good job,rabbit!
What a pity rabbit!
*/