题目描述:
在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对应关系如下:
距离s           票价
0<S<=L1         C1
L1<S<=L2        C2
L2<S<=L3        C3
输入保证0<L1<L2<L3<10^9,0<C1<C2<C3<10^9。
每两个站之间的距离不超过L3。
当乘客要移动的两个站的距离大于L3的时候,可以选择从中间一个站下车,然后买票再上车,所以乘客整个过程中至少会买两张票。
现在给你一个 L1,L2,L3,C1,C2,C3。然后是A B的值,其分别为乘客旅程的起始站和终点站。
然后输入N,N为该线路上的总的火车站数目,然后输入N-1个整数,分别代表从该线路上的第一个站,到第2个站,第3个站,……,第N个站的距离。
根据输入,输出乘客从A到B站的最小花费。
输入:
以如下格式输入数据:
L1  L2  L3  C1  C2  C3
A  B
N
a[2]
a[3]
……
a[N]
输出:
可能有多组测试数据,对于每一组数据,
根据输入,输出乘客从A到B站的最小花费。
样例输入:
1 2 3 1 2 3
1 2
2
2
样例输出:
2

这道题真是一个惨痛的回忆。
开始的思路是普通的动态规划思路,即经典的分割问题,最后通过的代码如下
 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#define MAX 300
#define inf 10000000009 long long minCost[MAX][MAX];
long long dis[MAX][MAX];
long long dis0[MAX]; int main(int argc, char const *argv[])
{
long long L1, L2, L3, C1, C2, C3;
//freopen("input.txt","r",stdin);
while(scanf("%lld %lld %lld %lld %lld %lld",&L1, &L2, &L3, &C1, &C2, &C3) != EOF)
{
int A, B;
int N;
scanf("%d %d",&A,&B);
scanf("%d",&N);
dis0[] = ;
for(int i = ; i <= N; i++) {
scanf("%lld",&dis0[i]);
}
for(int l = ; l <= N - ; l++) {
//length from 1 to N - 1
for(int i = ; i <= N - l; i++) {
//start from i to N - l
int j = i + l;
//end is i + l
dis[i][j] = dis0[j] - dis0[i];
if(dis[i][j] <= L1) {
minCost[i][j] = C1;
}
else if(dis[i][j] <= L2) {
minCost[i][j] = C2;
}
else if(dis[i][j] <= L3) {
minCost[i][j] = C3;
}
else {
minCost[i][j] = inf;
} for(int k = i + ; k <= j-; k++) {
long long int q = minCost[i][k] + minCost[k][j];
if(q < minCost[i][j]) {
minCost[i][j] = q;
}
}
}
}
if(A < B) {
printf("%lld\n",minCost[A][B]);
}
else if(A > B){
printf("%lld\n",minCost[B][A]);
}
else {
printf("%d\n",);
} }
return ;
}

但代码一开始提交了n次都没有通过,经过很长时间的排查,终于发现了原因。一开始我设的inf是

1000000009,WA改成了

10000000009后就AC了。

之后我发现没必要去算出每两个点之间的最小花费,只需要计算出从A到B之间的最小花费即可,dis数组也不需要

代码如下:

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#define MAX 300
#define inf 10000000009 long long minCost[MAX][MAX];
long long dis0[MAX]; int main(int argc, char const *argv[])
{
long long L1, L2, L3, C1, C2, C3;
//freopen("input.txt","r",stdin);
while(scanf("%lld %lld %lld %lld %lld %lld",&L1, &L2, &L3, &C1, &C2, &C3) != EOF)
{
int A, B;
int N;
scanf("%d %d",&A,&B);
scanf("%d",&N); for(int i = ; i <= N; i++) {
scanf("%lld",&dis0[i]);
}
if(A > B) {
int temp = A;
A = B;
B = temp;
}
long long n = B - A;
dis0[] = ;
minCost[A][A] = ;
for(int l = ; l <= n; l++) {
//length from 1 to N - 1
for(int i = A; i <= A + n - l; i++) {
//start from i to N - l
int j = i + l;
//end is i + l
long long temp = dis0[j] - dis0[i];
if(temp <= L1) {
minCost[i][j] = C1;
}
else if(temp <= L2) {
minCost[i][j] = C2;
}
else if(temp <= L3) {
minCost[i][j] = C3;
}
else {
minCost[i][j] = inf;
} for(int k = i + ; k <= j-; k++) {
long long int q = minCost[i][k] + minCost[k][j];
if(q < minCost[i][j]) {
minCost[i][j] = q;
}
}
}
}
printf("%lld\n",minCost[A][B]); }
return ;
}

但是我们研究一下会发现,如果两地的距离小于L3,则它们之间的最小花费必然在C1,C2,C3之间,所以若将minCost改为一维数组,将i作为中间点,j作为终点,当i到j的距离小于L3时,minCost[j] = min (minCost[j], minCost[i] + Ci); 所以遍历i时,选取与其距离小于L3的j,即可。代码如下:

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#define MAX 150
#define inf 10000000009 long long minCost[MAX];
long long dis0[MAX]; int main(int argc, char const *argv[])
{
long long L1, L2, L3, C1, C2, C3;
//freopen("input.txt","r",stdin);
while(scanf("%lld %lld %lld %lld %lld %lld",&L1, &L2, &L3, &C1, &C2, &C3) != EOF)
{
int A, B;
int N; scanf("%d %d",&A,&B);
scanf("%d",&N);
dis0[] = ;
for(int i = ; i <= N; i++) {
scanf("%lld",&dis0[i]);
minCost[i] = inf;
}
if(A > B) {
int temp = A;
A = B;
B = temp;
}
minCost[A] = ;
for(int i = A; i < B; i++) {
for(int j = i + ; j <= B; j++) {
long long int temp;
if(dis0[j] - dis0[i] <= L1) {
temp = C1;
}
else if(dis0[j] - dis0[i] <= L2) {
temp = C2;
}
else if(dis0[j] - dis0[i] <= L3) {
temp = C3;
}
else {
break;
}
long long q = minCost[i] + temp;
if(minCost[j] > q) {
minCost[j] = q;
}
}
}
printf("%lld\n",minCost[B]);
}
return ;
}

因为两个站的最大距离不超过L3,所以从A站到j站,中间必然会经过距离j站距离小于L3的某站,故minCost[j]在遍历时中间的分割点必然在这些站之间,所以可以这样化简

九度oj 题目1086:最小花费的更多相关文章

  1. 九度oj题目&amp;吉大考研11年机试题全解

    九度oj题目(吉大考研11年机试题全解) 吉大考研机试2011年题目: 题目一(jobdu1105:字符串的反码).    http://ac.jobdu.com/problem.php?pid=11 ...

  2. 九度oj 题目1007:奥运排序问题

    九度oj 题目1007:奥运排序问题   恢复 题目描述: 按要求,给国家进行排名. 输入:                        有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号 ...

  3. 九度OJ 题目1384:二维数组中的查找

    /********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...

  4. hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  5. 九度OJ 1502 最大值最小化(JAVA)

    题目1502:最大值最小化(二分答案) 九度OJ Java import java.util.Scanner; public class Main { public static int max(in ...

  6. 九度oj 题目1087:约数的个数

    题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...

  7. 九度OJ题目1105:字符串的反码

    tips:scanf,cin输入字符串遇到空格就停止,所以想输入一行字符并保留最后的"\0"还是用gets()函数比较好,九度OJ真操蛋,true?没有这个关键字,还是用1吧,还是 ...

  8. 九度oj题目1009:二叉搜索树

    题目描述: 判断两序列是否为同一二叉搜索树序列 输入:                        开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...

  9. 九度oj题目1002:Grading

    //不是说C语言就是C++的子集么,为毛printf在九度OJ上不能通过编译,abs还不支持参数为整型的abs()重载 //C++比较正确的做法是#include<cmath.h>,cou ...

随机推荐

  1. BZOJ1485: [HNOI2009]有趣的数列(Catalan数,质因数分解求组合数)

    题意 挺简洁的. 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<…<a ...

  2. Android 滑动RecyclerView时隐藏部分控件

    在使用RecyclerView控件时,上下拖动控件时的时候,需要实时的隐藏与显示部分控件,已到达很好的用户体验.   原理很简单,当RecyclerView拖动至最上层时显示控件,当RecyclerV ...

  3. Grace Huang 2017/1/12

    原文 Huang doesn't think of acting as pretending to be someone else.Rather,she considers it an opportu ...

  4. MFC技术积累——基于MFC对话框类的那些事儿3

    3.3.2 创建图形画刷来实现位图加载 1.首先在Resource View中导入一幅位图,位图大小96×96像素: 2.其次在主对话框中添加一个静态文本资源,ID号是IDC_BITMAPAREA,添 ...

  5. 安装vc++6.0的步骤

    我们学习计算机,就必须要先将编程的c语言学好,打好基础,学习c语言最好的方法就是多上机联系,对于联系我们需要在自己的电脑上安装vc++6.0来进行平日里的联系.1.打开电脑进行联网,打开浏览器搜索vc ...

  6. 使用xcode workspace 多个project协同工作

    一般的某个应用单独新建一个 project 就可以了,然后把所有的程序文件都放在里面,这个可以满足大部分普通的需求,但是有时候,项目有可能要使用其他的项目文件,或者引入其他的静态库文件,这个时候 wo ...

  7. 一次线上mysql死锁分析

    一.现象 发运车次调用发车接口时发生异常,后台抛出数据库死锁日志. 二.原因分析 通过日志可以看出事务T1等待 heap no 8的行锁 (X locks 排他锁) 事务T2持有heap no 8的行 ...

  8. centos7下添加开机启动

    在/etc/systemd/system下创建weblogic .Service touch weblogic.Service 添加启动权限 chmod +x weblogic.Service 编辑w ...

  9. Elementary OS上eclipse卡死问题

    解决: 1.可以用  sudo ./eclipse -vm /home/username/jdk_path/bin/java 启动但是启动后仍有显示问题. 2. 修改 eclipse.ini 在 -- ...

  10. Bluefruit LE Sniffer - Bluetooth Low Energy (BLE 4.0) - nRF51822 驱动安装及使用

    BLE Sniffer https://www.adafruit.com/product/2269 Bluefruit LE Sniffer - Bluetooth Low Energy (BLE 4 ...