boj1074_Candy的魔法

来源:互联网 发布:算法工程师做什么 编辑:程序博客网 时间:2024/04/20 07:16

Candy的魔法 Submit: 830   Accepted:178 Time Limit: 1000MS  Memory Limit: 65536KDescription
小蚂蚁的家在X轴的原点上,他的学校在X轴的N点上。
小蚂蚁从家里出发,沿X轴正方向前进(不能往回走),去学校里上课,他的本能速度是每两秒一个单位。由于小蚂蚁的速度之慢,老师担心他会迟到,就在途中的某些点上放了具有魔法的糖果(每个位置要么没放,要么只放了一个),每个糖果有一定的魔法值b,他能使小蚂蚁将以每秒1个单位的速度移动b秒,在这个魔法期间之内它只能向前移动,不能停下,也不能吃其他糖果。当然了,小蚂蚁可以自己选择是否要吃糖果,以及吃哪些位置上的糖果。他也只能朝向学校的方向走,而不能掉头。
现在给出你学校的位置N,以及糖果的放置情况,请你计算小蚂蚁到达学校至少需要多久。
Input
多组数据测试。数据以两个0结束输入。
每组数据包括两部分:第一行两个整数N(1< N <= 1000000000),M(0 <= M <= 50),N为学校的位置,M表示老师在途中放置的糖果的数目;
接下来的M行里,每行两个整数a(1<= a <= N),b(1<=b<=10000),a表示糖果位置,b表示对应糖果的魔法值。
Output
对每一组测试输出,输出小蚂蚁至少需要多少时间才能到达学校。每组数据的输出应该占一行。
Sample Input
7 2
2 2
3 4
5 3
3 1
1 2
4 2
0 0
Sample Output
10
7

View Code
 1 #include<iostream>
2 using namespace std;
3 typedef struct candy{
4 int a;
5 int b;
6 }candy;
7 bool cmp(const candy &x, const candy &y); //用STL的sort()排序,acm常用快攻利器
8 bool get_dest(int ,int ,int );
9 int mymin(int ,int );
10
11 int dp[50]; //设dp[i]为从这点开始(即前面没有candy),到达终点的最短时间。
12 candy c[50];
13 int main()
14 {
15 int N;
16 int M,i;
17 while(1)
18 {
19 scanf("%d%d",&N,&M);
20 if(N==0 && M==0) break;
21 if(M==0)
22 {
23 printf("%d\n",2*N);
24 continue;
25 }
26 memset(dp,0,sizeof(dp));
27 for(i=0;i<M;i++)
28 scanf("%d%d",&c[i].a,&c[i].b);
29
30 sort(c,c+M,cmp);
31 if(get_dest(c[M-1].a,c[M-1].b,N)) dp[M-1]=2*c[M-1].a+2*(N-c[M-1].a-c[M-1].b)+c[M-1].b; //从后面往前dp,最后一点能到达恰好能终点
32 else dp[M-1]=2*N; //最后一点到达不到终点
33
34 for(i=M-2;i>=0;i--)
35 {
36 if(!get_dest(c[i].a,c[i].b,N)) dp[i]=dp[i+1]; //当前点到达不了终点
37 else //当前点可以到达终点
38 {
39 int uneat=dp[i+1]; //不吃这点
40 int eat=-1; //吃这点
41 for(int k=i+1;k<M;k++) //考虑吃了这点后的后续点
42 {
43 if( (c[i].a+c[i].b)<=c[k].a )
44 {
45 eat=dp[k]-c[i].b;
46 break;
47 }
48 }
49 if(eat==-1) eat=2*c[i].a+c[i].b+2*(N-c[i].a-c[i].b);
50 dp[i]=mymin(eat,uneat);
51 }
52 }
53
54 printf("%d\n",dp[0]);
55 }
56 system("pause");
57 return 0;
58 }
59
60 bool cmp(const candy &x, const candy &y)
61 {
62 return x.a<y.a;
63 }
64 bool get_dest(int a,int b,int c)
65 {
66 if((a+b)>c) return false;
67 else return true;
68 }
69 int mymin(int a,int b)
70 {
71 return (a<=b)?a:b;
72 }

 

//这道题是从5月份开到的,一直到现在才ac,当然中间的时间没有思考。之前一直都是考虑从前面往后面dp,但一直都想不出思路。换一个角度就好了,从后面往前dp,呵呵!

0 0
原创粉丝点击