#806. [Junior] Contest 19/10/7/5 - 公交乘车

(第六篇题解,请多指教)

家人们九月份要去参加CSP-J初赛已经开始害怕了qwq

当然,作者在一位朋友(作者偷懒,文章还得我帮 t a ta ta改)的提醒下报上了洛谷的预赛
美丽善良大方的作者当然得分享一下啦(帮作者该题解的我想说:这是假的,假的,假的!!!)

今年要参加比赛的宝子们戳这个

好了正文开始

Step 1 分析题目

题目描述

一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里数来付费。例如下表就是一个费用的单子。

没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1≤n≤100),它可以通过无限次的换车来完成旅程。最后要求费用最少。

费用单子如下:

请添加图片描述

输入格式

第一行:十个整数,分别表示行走1到10公里的费用(s≤500)。注意这些数并无实际的经济意义

即行驶10公里费用可能比行驶一公里少//这里是这道题的重点

第二行: 一个整数n,表示旅客的总路程数。

输出格式

仅一个整数表示最少费用。

样例输入

12 21 31 40 49 58 69 79 90 101

15

样例输出

147

Step 2 思路简述

读完题,我们可以轻而易举的得知这是一道完全背包问题,先上模板再分析得出状态转移方程即可

知识点模板(dalao们可自动跳过)

#include<bits/stdc++.h>
using namespace std;
long long f[10000005],w[1005],c[1005];
int main(){
	int n,m;
	cin>>m>>n;
	for(int i=1;i<=n;i++){
		cin>>w[i]>>c[i];
		for(int j=w[i];j<=m;j++)
			f[j]=max(f[j],f[j-w[i]]+c[i]);
	}
	cout<<"max="<<f[m];
}

怎么说,总感觉这个模板对我们解决这道题并没有太大用处 …(就算没用处也看看吧)

进一步思路

自己如果分析的话在草稿纸上列一遍就好,但是这里我就带大家列一遍表格得出状态转移方程(帮作者该题解的我:恼火!!!!为什么和我写的一模一样!!!)

请添加图片描述

由此可知,状态转移方程是 f [ j ] = m i n ( f [ j ] , f [ j − i ] + a [ i ] ) f[j]=min(f[j],f[j−i]+a[i]) f[j]=min(f[j],f[ji]+a[i]),那么即可得出最终结果(一模一样2.0)

Step 3 完整AC代码

#include<bits/stdc++.h>
using namespace std;
int MAX = 0x3f3f3f3f,dp[501],val[11];
int main()
{	
	freopen("buses.in","r",stdin);
	freopen("buses.out","w",stdout);
    int n;
    for(int i = 1; i <= 10; i ++) cin >> val[i];
    cin >> n;
    for(int i = 1; i <= n; i ++)
    {
        dp[i] = MAX;
        for(int j = 1; j <= 10 && i - j >= 0; j ++)
        dp[i] = min(dp[i - j] + val[j],dp[i]);
        }
        cout << dp[n];
        return 0;
}

题解结束,感谢观看(祝大家CSP-J初赛加油!)

特别鸣谢szx同学提供模板and表格思路(没错就是我帮 t a ta ta改,原文点我

zyx同学指导完善Mark Down语法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值