JDOJ 1404: VIJOS-P1292 火车票
https://neooj.com/oldoj/problem.php?id=1404
Description
一个铁路线上有n(2< =n< =10000)个火车站,每个火车站到该线路的首发火车站距离都是已知的。任意两站之间的票价如下表所示: 站之间的距离 - X 票价 0< X< =L1 C1 L1< X< =L2 C2 L2< X< =L3 C3 其中L1,L2,L3,C1,C2,C3都是已知的正整数,且(1 < = L1 < L2 < L3 < = 10^9, 1 < = C1 < C2 < C3 < = 10^9)。显然若两站之间的距离大于L3,那么从一站到另一站至少要买两张票。注意:每一张票在使用时只能从一站开始到另一站结束。 现在需要你对于给定的线路,求出从该线路上的站A到站B的最少票价。你能做到吗?
Input
输入文件的第一行为6个整数, L1, L2, L3, C1, C2, C3 (1 < = L1 < L2 < L3 < = 10^9, 1 < = C1 < C2 < C3 < = 10^9) ,这些整数由空格隔开.第二行为火车站的数量N (2 < = N < = 10000).第三行为两个不同的整数A、B,由空格隔开。接下来的 N-1 行包含从第一站到其他站之间的距离.这些距离按照增长的顺序被设置为不同的正整数。相邻两站之间的距离不超过L3. 两个给定火车站之间行程花费的最小值不超过10^9,而且任意两站之间距离不超过 10^9。
Output
输出文件中只有一个数字,表示从A到B要花费的最小值.
Sample Input
3 6 8 20 30 40 7 2 6 3 7 8 13 15 23
Sample Output
70
动态规划水题。
思路:
输入,加函数分类讨论计算花费,动归,输出。
cost函数我不多讲了,看代码应该没啥问题。
cost函数我不多讲了,看代码应该没啥问题。
主要讲动归部分。
从a到b枚举,答案是dp[b],因为题目中说了不存在买两张票的情况,所以不需要考虑多张票数。
设置状态为从起点到i的最小花费。
状态转移方程为:
dp[i]=min(dp[i],dp[j]+cost[j,i]);
这题完事。
然后你发现自己WA了几个点。
所以你开了long long
然后你AC了。
code:
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int l1,l2,l3,c1,c2,c3,n; int a,b; long long len[10001]; long long dp[10001]; long long cost(long long x,long long y) { if(len[y]-len[x]<=l3 && len[y]-len[x]>l2) return c3; if(len[y]-len[x]<=l2 && len[y]-len[x]>l1) return c2; if(len[y]-len[x]<=l1) return c1; } int main() { scanf("%d%d%d%d%d%d%d%d%d",&l1,&l2,&l3,&c1,&c2,&c3,&n,&a,&b); memset(dp,0x3f,sizeof(dp)); dp[a]=0; len[1]=0; for(int i=2;i<=n;i++) scanf("%lld",&len[i]); for(int i=a;i<=b;i++) for(int j=a;j<i;j++) if(len[i]-len[j]<=l3) dp[i]=min(dp[i],dp[j]+cost(j,i)); printf("%lld",dp[b]); return 0; }