多段决策问题 hdu 2059 zoj 2967

据说在很久很久以前,可怜的兔子经历了人生中最大的打击——赛跑输给乌龟后,心中郁闷,发誓要报仇雪恨,于是躲进了杭州下沙某农业园卧薪尝胆潜心修炼,终于练成了绝技,能够毫不休息得以恒定的速度(VR m/s)一直跑。兔子一直想找机会好好得教训一下乌龟,以雪前耻。 
最近正值HDU举办50周年校庆,社会各大名流齐聚下沙,兔子也趁此机会向乌龟发起挑战。虽然乌龟深知获胜希望不大,不过迫于舆论压力,只能接受挑战。 
比赛是设在一条笔直的道路上,长度为L米,规则很简单,谁先到达终点谁就算获胜。 
无奈乌龟自从上次获胜以后,成了名龟,被一些八卦杂志称为“动物界的刘翔”,广告不断,手头也有了不少积蓄。为了能够再赢兔子,乌龟不惜花下血本买了最先进的武器——“"小飞鸽"牌电动车。这辆车在有电的情况下能够以VT1 m/s的速度“飞驰”,可惜电池容量有限,每次充满电最多只能行驶C米的距离,以后就只能用脚来蹬了,乌龟用脚蹬时的速度为VT2 m/s。更过分的是,乌龟竟然在跑道上修建了很多很多(N个)的供电站,供自己给电动车充电。其中,每次充电需要花费T秒钟的时间。当然,乌龟经过一个充电站的时候可以选择去或不去充电。 
比赛马上开始了,兔子和带着充满电的电动车的乌龟并列站在起跑线上。你的任务就是写个程序,判断乌龟用最佳的方案进军时,能不能赢了一直以恒定速度奔跑的兔子。
Input本题目包含多组测试,请处理到文件结束。每个测试包括四行: 
第一行是一个整数L代表跑道的总长度 
第二行包含三个整数N,C,T,分别表示充电站的个数,电动车冲满电以后能行驶的距离以及每次充电所需要的时间 
第三行也是三个整数VR,VT1,VT2,分别表示兔子跑步的速度,乌龟开电动车的速度,乌龟脚蹬电动车的速度 
第四行包含了N(N<=100)个整数p1,p2...pn,分别表示各个充电站离跑道起点的距离,其中0<p1<p2<...<pn<L 
其中每个数都在32位整型范围之内。 
Output当乌龟有可能赢的时候输出一行 “What a pity rabbit!"。否则输出一行"Good job,rabbit!";
题目数据保证不会出现乌龟和兔子同时到达的情况。Sample Input
100
3 20 5
5 8 2
10 40 60
100
3 60 5
5 8 2
10 40 60
Sample Output
Good job,rabbit!
What a pity rabbit!


 思路:   dp[i][j]   表示到达第i  个充电器 后 的最短时间  j==0  表示 不充电,,j==1  表示充电。


代码: 

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define N 105
#define inf 0x3f3f3f3f

using namespace std;

double d[N];
double time1,time2;
double dp[N][2];
double v1,v2;
double ttime;
double l;
int n;
double c,t;
double vr;

int main()
{
	while(scanf("%lf",&l)!=EOF)
	{
		scanf("%d %lf %lf",&n,&c,&t);
		scanf("%lf %lf %lf",&vr,&v1,&v2);
		
		time1=l/vr;
		
		n++;
		d[0]=0;
		for(int i=1;i<n;i++){
			scanf("%lf",&d[i]);
		}
		d[n]=l;
		
		for(int i=0;i<=n;i++)
		{
			for(int j=0;j<2;j++) dp[i][j]=inf*1.0;
		}
		
		dp[0][0]=dp[0][1]=0;
		//printf("lalla\n");
		
		for(int i=1;i<=n;i++){
			    for(int j=0;j<i;j++)
				{
					double dis=d[i]-d[j];
					ttime=0;
					double tt1,tt2;
					tt1=tt2=0;
					tt1=dis/v2;
					if(dis<=c){
						tt2=dis/v1;
					}
					else{
						dis=dis-c;
						tt2+=c/v1;
						tt2+=dis/v2;
				    }
				    
				    dp[i][0]=min(dp[i][0],dp[j][0]+tt1);
				    dp[i][0]=min(dp[i][0],dp[j][1]+tt2);
				    
				    dp[i][1]=min(dp[i][1],dp[j][0]+tt1+t);
				    dp[i][1]=min(dp[i][1],dp[j][1]+tt2+t);
					
				}
		
		}
		
		dp[n][1]-=t;
		
		time2=min(dp[n][0],dp[n][1]);
		
		
		//printf("time1 : %lf\n",time1);
		//printf("time2 : %lf\n",time2);
		if(time2<=time1){
			cout<<"What a pity rabbit!\n";
		}
		else
		{
			cout<<"Good job,rabbit!\n";
		}
		
	}
	
	return 0;
}



Hurdles of 110m

Time Limit: 2 Seconds       Memory Limit: 65536 KB

In the year 2008, the 29th Olympic Games will be held in Beijing. This will signify the prosperity of China and Beijing Olympics is to be a festival for people all over the world as well.

Liu Xiang is one of the famous Olympic athletes in China. In 2002 Liu broke Renaldo Nehemiah's 24-year-old world junior record for the 110m hurdles. At the 2004 Athens Olympics Games, he won the gold medal in the end. Although he was not considered as a favorite for the gold, in the final, Liu's technique was nearly perfect as he barely touched the sixth hurdle and cleared all of the others cleanly. He powered to a victory of almost three meters. In doing so, he tied the 11-year-old world record of 12.91 seconds. Liu was the first Chinese man to win an Olympic gold medal in track and field. Only 21 years old at the time of his victory, Liu vowed to defend his title when the Olympics come to Beijing in 2008.

In the 110m hurdle competition, the track was divided into N parts by the hurdle. In each part, the player has to run in the same speed; otherwise he may hit the hurdle. In fact, there are 3 modes to choose in each part for an athlete -- Fast Mode, Normal Mode and Slow Mode. Fast Mode costs the player T1 time to pass the part. However, he cannot always use this mode in all parts, because he needs to consume F1 force at the same time. If he doesn't have enough force, he cannot run in the part at the Fast Mode. Normal Mode costs the player T2time for the part. And at this mode, the player's force will remain unchanged. Slow Mode costs the player T3 time to pass the part. Meanwhile, the player will earn F2 force as compensation. The maximal force of a player is M. If he already has M force, he cannot earn any more force. At the beginning of the competition, the player has the maximal force.

The input of this problem is detail data for Liu Xiang. Your task is to help him to choose proper mode in each part to finish the competition in the shortest time.

Input

Standard input will contain multiple test cases. The first line of the input is a single integer T (1 <= T <= 50) which is the number of test cases. And it will be followed by T consecutive test cases.

Each test case begins with two positive integers N and M. And following N lines denote the data for the N parts. Each line has five positive integers T1 T2 T3 F1 F2. All the integers in this problem are less than or equal to 110.

Output

Results should be directed to standard output. The output of each test case should be a single integer in one line, which is the shortest time that Liu Xiang can finish the competition.

Sample Input

2
1 10
1 2 3 10 10
4 10
1 2 3 10 10
1 10 10 10 10
1 1 2 10 10
1 10 10 10 10

Sample Output

1
6

Hint

For the second sample test case, Liu Xiang should run with the sequence of Normal Mode, Fast Mode, Slow Mode and Fast Mode.

题意:  现在有 n  段 路需要你去跑  顺序跑  ,你可以用高速 跑  但是消耗一定的体力 但是时间短,也可以中速跑 时间稍长,但是不耗费体力,, 你也可以用低速跑 但是时间短, 但是你可以赚到一些体力。  问你最少的时间跑完这n 短路

思路:  dp[ i ][ j ]  表示 跑完第i 段  剩余体力为j  的最短时间。

代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define inf 0x3f3f3f3f
#define N 125

using namespace std;

int dp[N][N*10];
int n,m;
int t1[N],t2[N],t3[N],p1[N],p2[N];

int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n>>m;
		
		memset(dp,inf,sizeof(dp));
		for(int i=0;i<=m;i++) dp[0][i]=0;
		
		for(int i=1;i<=n;i++)
		{
			scanf("%d %d %d %d %d",&t1[i],&t2[i],&t3[i],&p1[i],&p2[i]);
		}
		
		for(int i=1;i<=n;i++){
				for(int j=0;j<=m;j++){
					
				dp[i][j]=min(dp[i-1][j]+t2[i],dp[i][j]);
				if(j+p1[i]<=m) dp[i][j]=min(dp[i][j],dp[i-1][j+p1[i]]+t1[i]);
				
				int tmp=min(m,j+p2[i]);
				dp[i][tmp]=min(dp[i][tmp],dp[i-1][j]+t3[i]);
			}
		}
		int ans=inf;
		
		for(int i=0;i<=m;i++) ans=min(ans,dp[n][i]);
		
		printf("%d\n",ans);
		
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值