九度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 ...
随机推荐
- C语言abort函数
C语言编程入门教程,C语言库函数的abort函数的作用是异常终止一个进程,意味着abort后面的代码将不再执行. #include<stdio.h> #include<stdlib. ...
- 查找算法(顺序查找、二分法查找、二叉树查找、hash查找)
查找功能是数据处理的一个基本功能.数据查找并不复杂,但是如何实现数据又快又好地查找呢?前人在实践中积累的一些方法,值得我们好好学些一下.我们假定查找的数据唯一存在,数组中没有重复的数据存在. (1)顺 ...
- Yii2.0 Cookies机制和使用方法
在实际的项目开发过程中,用到了Yii2.0 Cookies机制!但是遇到一个十分奇葩的问题,同一个YII框架,backend下Cookies能够正常存储于客户端,但是frontend始终不行.文章的最 ...
- License开源许可协议
开源许可协议 License是软件的授权许可,表述了你获得代码后拥有的权利,可以对别人的作品进行何种操作,何种操作又是被禁止的. 开源许可证种类 Open Source Initiative http ...
- 【GIMP学习】抠图方法二则
之前抠图都比较二,懒人我尝试过在线抠图软件.以及在线PS简易版,真的都很不好用,前者简单粗暴,后者我遇到各种储存不能的bug. 在ubuntu的环境下有一个功能可以和PS相媲美的功能强大图片处理软件G ...
- iOS perform action after period of inactivity (no user interaction)
代码看完后感觉非常优秀 http://stackoverflow.com/questions/8085188/ios-perform-action-after-period-of-inactivity ...
- k8s集群介绍
Kubernetes集群组件 一个典型的Kubernetes集群由多个工作节点和一个集群控制节点,以及一个集群状态存储系统etcd组成.其中Master节点负责整个集群管理工作,为集群提供管理接口,并 ...
- CPP-基础:非静态成员函数后面加const,以及mutable修饰成员变量
非静态成员函数后面加const(加到非成员函数或静态成员后面会产生编译错误),表示成员函数隐含传入的this指针为const指针,决定了在该成员函数中,任意修改它所在的类的成员的操作都是不允许的(因为 ...
- python之道07
2.用户输入一个数字,判断一个数是否是水仙花数. 水仙花数是一个三位数, 三位数的每一位的三次方的和还等于这个数. 那这个数就是一个水仙花数, 例如: 153 = 1******3 + 5****** ...
- bootstrap历练实例: 基本胶囊式的导航菜单
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...