九度oj 题目1086:最小花费
- 题目描述:
-
在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对应关系如下:距离s 票价0<S<=L1 C1L1<S<=L2 C2L2<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 C3A BNa[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:最小花费的更多相关文章
- 九度oj题目&吉大考研11年机试题全解
九度oj题目(吉大考研11年机试题全解) 吉大考研机试2011年题目: 题目一(jobdu1105:字符串的反码). http://ac.jobdu.com/problem.php?pid=11 ...
- 九度oj 题目1007:奥运排序问题
九度oj 题目1007:奥运排序问题 恢复 题目描述: 按要求,给国家进行排名. 输入: 有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号 ...
- 九度OJ 题目1384:二维数组中的查找
/********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...
- hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人
钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- 九度OJ 1502 最大值最小化(JAVA)
题目1502:最大值最小化(二分答案) 九度OJ Java import java.util.Scanner; public class Main { public static int max(in ...
- 九度oj 题目1087:约数的个数
题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...
- 九度OJ题目1105:字符串的反码
tips:scanf,cin输入字符串遇到空格就停止,所以想输入一行字符并保留最后的"\0"还是用gets()函数比较好,九度OJ真操蛋,true?没有这个关键字,还是用1吧,还是 ...
- 九度oj题目1009:二叉搜索树
题目描述: 判断两序列是否为同一二叉搜索树序列 输入: 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...
- 九度oj题目1002:Grading
//不是说C语言就是C++的子集么,为毛printf在九度OJ上不能通过编译,abs还不支持参数为整型的abs()重载 //C++比较正确的做法是#include<cmath.h>,cou ...
随机推荐
- BZOJ1485: [HNOI2009]有趣的数列(Catalan数,质因数分解求组合数)
题意 挺简洁的. 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<…<a ...
- Android 滑动RecyclerView时隐藏部分控件
在使用RecyclerView控件时,上下拖动控件时的时候,需要实时的隐藏与显示部分控件,已到达很好的用户体验. 原理很简单,当RecyclerView拖动至最上层时显示控件,当RecyclerV ...
- Grace Huang 2017/1/12
原文 Huang doesn't think of acting as pretending to be someone else.Rather,she considers it an opportu ...
- MFC技术积累——基于MFC对话框类的那些事儿3
3.3.2 创建图形画刷来实现位图加载 1.首先在Resource View中导入一幅位图,位图大小96×96像素: 2.其次在主对话框中添加一个静态文本资源,ID号是IDC_BITMAPAREA,添 ...
- 安装vc++6.0的步骤
我们学习计算机,就必须要先将编程的c语言学好,打好基础,学习c语言最好的方法就是多上机联系,对于联系我们需要在自己的电脑上安装vc++6.0来进行平日里的联系.1.打开电脑进行联网,打开浏览器搜索vc ...
- 使用xcode workspace 多个project协同工作
一般的某个应用单独新建一个 project 就可以了,然后把所有的程序文件都放在里面,这个可以满足大部分普通的需求,但是有时候,项目有可能要使用其他的项目文件,或者引入其他的静态库文件,这个时候 wo ...
- 一次线上mysql死锁分析
一.现象 发运车次调用发车接口时发生异常,后台抛出数据库死锁日志. 二.原因分析 通过日志可以看出事务T1等待 heap no 8的行锁 (X locks 排他锁) 事务T2持有heap no 8的行 ...
- centos7下添加开机启动
在/etc/systemd/system下创建weblogic .Service touch weblogic.Service 添加启动权限 chmod +x weblogic.Service 编辑w ...
- Elementary OS上eclipse卡死问题
解决: 1.可以用 sudo ./eclipse -vm /home/username/jdk_path/bin/java 启动但是启动后仍有显示问题. 2. 修改 eclipse.ini 在 -- ...
- 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 ...