HDU2059龟兔赛跑
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2059
典型的动态规划,这个题没有想太复杂,直接用最简单的dp过了,分类说是数塔变种,但是没有找到思路。所以还是朴素的dp过了,wa了三次,后面还是ac了。hdu的数据确实没有poj的强。说下我的思路,代码写的很挫,肯定没人能看懂。分为两种情况,1、一次油也不加。2、至少加一次油,设d[i][j]为到第i个加油站加了j次油的最快时间。1<=i<=n, 1<=j<=i;代码如下,可供对拍:
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <set> #include <string.h> using namespace std; #define inf 0x3f3f3f3f int n; double l, c, t, vr, vt1, vt2; double d[105], a[105][105]; bool cal(){ for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) a[i][j] = inf; for (int i = 1; i <= n; i++){ if (d[i] <= c) a[i][1] = d[i] / vt1 + t; else a[i][1] = c / vt1 + (d[i] - c) / vt2 + t; } for (int i = 1; i <= n; i++){ for (int j = 2; j <= i; j++){ double maxf = 1000000000.0; for (int k = 1; k < i; k++){ double time = a[k][j - 1]; double dis = d[i] - d[k]; if (dis <= c)time += dis / vt1; else time += (dis - c) / vt2 + c / vt1; if (time < maxf)maxf = time; } a[i][j] = maxf + t; } } double minf = 1000000000.0; for (int i = 1; i <= n; i++){ double time = 100000000.0; for (int j = 1; j <= i; j++){ if (time > a[i][j])time = a[i][j]; } double dis = l - d[i]; if (dis <= c)time += dis / vt1; else time += c / vt1 + (dis - c) / vt2; if (minf > time)minf = time; } double temp; if (l <= c)temp = l / vt1; else temp = c / vt1 + (l - c) / vt2; minf = min(minf, temp); if (minf > l / vr)return true; return false; } int main() { while (cin>>l){ cin>>n>>c>>t; cin>>vr>>vt1>>vt2; d[0] = 0; for (int i = 1; i <= n; i++){ cin>>d[i]; } if (cal()) cout<<"Good job,rabbit!"<<endl; else cout<<"What a pity rabbit!"<<endl; } return 0; }