• 2020qbxt D1T3 停车


    嗯...

    题目:

    【问题描述】

    市中心有一个环形的停车场,编号1到n,现在有m个车要停,停在每个位置会有不同的费用。为了方便,不允许两辆车停在相邻的位置,请问停好所有车的最小花费是多少?

    【输入格式】

    第一行包含两个正整数n, m,保证n>=2m-1

    第二行包含n个正整数,表示停在i位置的费用

    【输出格式】

    输出一个整数,表示停好所有车的最小花费是多少

    【样例输入】

    7 3

    1 2 3 4 5 6 7

    【样例输出】

    9

    【样例说明】

    停在1 3 5

    【数据规模与约定】

    20% n<=10

    40% n<=100

    60% n<=1000

    100% n<=100000 ai<=10000

     

    分析:

    这道题我们首先会考虑贪心。如果没有限制,只需要从小到大贪心即可。由于有了限制,考虑设计能够撤销之前操作。

    考虑一个性质的证明:

    如果有1 2 3 三个数中选择,如果不选2,那么一定会选1和3。这样的话如果选了2,删除1、3两个节点,把2的权值更改成a[1]+a[3]-a[2],相当于把2修改成了1和3。

    优先队列优化贪心可以做到O(nlogn),每次处理后用链表来删除。

     

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<queue>
     4 #define pa pair<int,int>
     5 using namespace std;
     6 
     7 int n,m,ans;
     8 int vis[10005],a[10005],L[10005],R[10005];
     9 priority_queue<pa,vector<pa>,greater<pa> >q;
    10 
    11 inline void del(int x){
    12     vis[x]=1;
    13     R[L[x]]=R[x];
    14     L[R[x]]=L[x];
    15 }
    16 
    17 int main(){
    18     scanf("%d%d",&n,&m);
    19     for(int i=1;i<=n;i++){
    20         scanf("%d",&a[i]);
    21         L[i]=(i==1)?n:i-1;
    22         R[i]=(i==n)?1:i+1;
    23         q.push(pa(a[i],i));
    24     }
    25     while(m--){
    26         while(vis[q.top().second]) q.pop();
    27         int x=q.top().second; q.pop();
    28         ans+=a[x];
    29         a[x]=a[L[x]]+a[R[x]]-a[x];
    30         del(L[x]); del(R[x]);
    31         q.push(pa(a[x],x));
    32     }
    33     printf("%d
    ",ans);
    34     return 0;
    35 }
    AC代码
  • 相关阅读:
    matlab代码学习_2018728
    理解面向对象过程中创造一个对象的步骤
    html字符及空格占位问题
    div中img(及文字等inline元素和block元素)的自动换行
    css布局居中
    css3前缀解决方案
    自己写一个树形导航菜单
    《JavaScript核心概念及实践》 读书笔记
    css常用属性
    windows下有个目录名称中间有空格 java读目录空格变成%20 处理方法
  • 原文地址:https://www.cnblogs.com/New-ljx/p/12203527.html
Copyright © 2020-2023  润新知