(第六篇题解,请多指教)
家人们九月份要去参加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[j−i]+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语法