阅读计划(book)
问题描述
暑假到了,Rick制定了一个长达M天的阅读计划。他一共有N本书,从1至N进行标号;Rick将它们从上至下摞成一堆。他每天都会读一本书,假设他要读编号为X的书,他会按照以下步骤:
1. 将这本书上方的所有书搬起来
2. 将这本书拿出来
3. 将搬起来的书摞回去
4. 看完后把这本书放到顶端
每本书都会有各自的重量,Rick不希望搬起太过重的书。于是他希望能重新安排这N本书的顺序,使得读完M本书之后,搬书的重量之和最小。
输入格式(book.in)
第一行两个整数N与M,分别代表书的数量和阅读的天数。
第二行N个整数,代表每本书的重量。
第三行M个整数,代表每天要读的书的编号。
输出格式(book.out)
一行一个整数,代表最小的重量之和。
样例输入
3 5
1 2 3
1 3 2 3 1
样例输出
12
数据范围与约束
对于30%的数据,N<=10.
对于100%的数据,2<=N<=500, 1<=M<=1000, 每本书重量不超过100.
解法:这是一道贪心题;
分析一下,当我们看完某一本书后,这本书一定会被放在这摞书的上面,那我们要省力的话,那不妨把它一开始就放到上面。
假如我只读一本书,那我直接放到最上的位置;
假如我只读两本书,考虑第一本书:因为无论怎样在第一天后它都会放到顶上,不
如就直接放在顶上。那第二本书放在第二个位置上是最优的。
假如我只读三本书,是类似的:考虑第三本书。在读完前两本书后,它们肯定会放
在最上方,所以放到第三位置是最优的。 (如果往上放一放,还可能给之前的其他
书增加重量)
所以我们贪心的策略就大致确定了:按照阅读的顺序从上往下放。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int n,m,ans;
int a[509],r[1009],t[509],C;
bool f[509];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
scanf("%d",&r[i]);
if(!f[r[i]]) t[++C]=r[i],f[r[i]]=1;
}
for(int i=1;i<=m;i++)
{
int j;
for(j=1;t[j]!=r[i];ans+=a[t[j]],j++);
for(int k=j;k>=2;k--) t[k]=t[k-1];
t[1]=r[i];
}
printf("%d",ans);
return 0;
}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步