• 阅读计划


    问题描述

    暑假到了,Rick制定了一个长达M天的阅读计划。他一共有N本书,从1N进行标号;Rick将它们从上至下摞成一堆。他每天都会读一本书,假设他要读编号为X的书,他会按照以下步骤:

    1. 将这本书上方的所有书搬起来

    2. 将这本书拿出来

    3. 将搬起来的书摞回去

    4. 看完后把这本书放到顶端

    每本书都会有各自的重量,Rick不希望搬起太过重的书。于是他希望能重新安排这N本书的顺序,使得读完M本书之后,搬书的重量之和最小。

    输入格式(book.in)

    第一行两个整数NM,分别代表书的数量和阅读的天数。

    第二行N个整数,代表每本书的重量。

    第三行M个整数,代表每天要读的书的编号。

    输出格式(book.out)

    一行一个整数,代表最小的重量之和。

    样例输入

    3 5

    1 2 3

    1 3 2 3 1

    样例输出

    12

    样例解释

    DAY1 1 3 2 – 搬起重量 = 0

    DAY2 1 3 2 – 搬起重量 = 1

    DAY3 3 1 2 – 搬起重量 = 4

    DAY4 2 3 1 – 搬起重量 = 2

    DAY5 3 2 1 – 搬起重量 = 5

    总和 = 0 + 1 + 4 + 2 + 5 = 12

    数据范围与约束

    对于30%的数据,N<=10.

    对于100%的数据,2<=N<=500, 1<=M<=1000, 每本书重量不超过100.

    思路:

      贪心,先读到的放在上边,最后模拟那个过程,把重量加起来。

    #include<iostream>
    #include<queue>
    #include<math.h>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,w[600];
    int q[1200],cnt,last[600],f[1200];
    int vis[600];
    int ans,tot;
    int main()
    {
        freopen("book.in","r",stdin);freopen("book.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)    scanf("%d",&w[i]);    
        for(int i=1,c;i<=m;i++)        
            scanf("%d",&q[++cnt]);
    
        for(int i=1;i<=m;i++)
        {
            if(!last[q[i]])    ans+=tot,tot+=w[q[i]],last[q[i]]=i;
            else{        
                    int t=last[q[i]]+1;
                    memset(vis,0,sizeof(vis)); 
                    
                    for(t;t<i;t++)
                    if(!vis[q[t]])    ans+=w[q[t]],vis[q[t]]=1;
                    last[q[i]]=i;
                }        
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    天文漫谈章测试题【第四章】
    天文漫谈章测试题【第三章】
    天文漫谈章测试题【第二章】
    天文漫谈-章测试题【第一章】
    天文漫谈期末考试
    《中国特色社会主义理论与实践》笔记 202001
    教育法学期末考试02MOOC
    教学法学期末考试MOOC01
    教育法学第九章单元测试MOOC
    在Linux平台上如何使用接静态库和共享库
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7248967.html
Copyright © 2020-2023  润新知