zoukankan      html  css  js  c++  java
  • Guard Duty (medium) Codeforces

    https://codeforces.com/contest/958/problem/E2

    首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小

    方法1:

    一个K^2的做法,有一定技巧

    https://www.cnblogs.com/void-f/p/8867585.html

    方法2:

    是可撤销贪心的模板?

    就是贪心的选权值最小的,但是在选完某一个位置i后把它前一个没有被删的位置pre[i]和后一个没有被删的位置nxt[i]删掉,将i的权值变为(-(i原来的权值)+(pre[i]原来的权值)+(nxt[i]原来的权值)),表示如果再选一次这个位置,就相当于不选i,改为选pre[i]和nxt[i]

    这样子搞是因为:由于每次是贪心的选权值最小的i,则单独选pre[i]和nxt[i]中任意一个都不可能比选i更优,只有当同时选pre[i]和nxt[i]时可能比选i要优

    细节并不能搞清楚...然而,这个算法运行得很正确

    有一个要注意的:如果选出的是最靠边上的i,那么显然i一定在最优解中(因为改为选i旁边的一定不会更优),直接把自身和与其相邻的删掉即可

    可以搞一个链表+堆维护这个东西

    错误记录:链表写错

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 #include<set>
     6 using namespace std;
     7 #define fi first
     8 #define se second
     9 #define mp make_pair
    10 #define pb push_back
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 typedef pair<int,int> pii;
    14 struct E
    15 {
    16     int nxt,pre,d;
    17 }e[500100];
    18 int a[500100];
    19 int K,n;
    20 set<pii> s;
    21 set<pii>::iterator i1;
    22 int an;
    23 int main()
    24 {
    25     int i,x,y;pii t;
    26     scanf("%d%d",&K,&n);
    27     for(i=1;i<=n;i++)    scanf("%d",&a[i]);
    28     sort(a+1,a+n+1);
    29     for(i=1;i<n;i++)    a[i]=a[i+1]-a[i];
    30     n--;
    31     for(i=1;i<=n;i++)
    32     {
    33         e[i].nxt=i+1;
    34         e[i].pre=i-1;
    35         e[i].d=a[i];
    36         s.insert(mp(e[i].d,i));
    37     }
    38     e[n].nxt=e[1].pre=0;
    39     for(i=1;i<=K;i++)
    40     {
    41         i1=s.begin();
    42         t=*i1;s.erase(i1);
    43         x=t.fi;y=t.se;
    44         an+=x;
    45         x=-x;
    46         if(!e[y].pre||!e[y].nxt)
    47         {
    48             if(e[y].pre)
    49             {
    50                 s.erase(mp(e[e[y].pre].d,e[y].pre));
    51                 e[e[e[y].pre].pre].nxt=0;
    52             }
    53             if(e[y].nxt)
    54             {
    55                 s.erase(mp(e[e[y].nxt].d,e[y].nxt));
    56                 e[e[e[y].nxt].nxt].pre=0;
    57             }
    58         }
    59         else
    60         {
    61             x+=e[e[y].pre].d;x+=e[e[y].nxt].d;
    62             s.erase(mp(e[e[y].pre].d,e[y].pre));
    63             s.erase(mp(e[e[y].nxt].d,e[y].nxt));
    64             e[y].pre=e[e[y].pre].pre;e[e[y].pre].nxt=y;
    65             e[y].nxt=e[e[y].nxt].nxt;e[e[y].nxt].pre=y;
    66             e[y].d=x;
    67             s.insert(mp(e[y].d,y));
    68         }
    69     }
    70     printf("%d",an);
    71     return 0;
    72 }
    View Code

    方法3:

    为什么说是什么带权二分?以后再说


    以下题改一下以上代码读入中n和K的顺序就可以A掉了??

    https://www.lydsy.com/JudgeOnline/problem.php?id=1150


    bzoj 2151 种树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2151

    洛谷P1792

    https://www.luogu.org/problemnew/show/P1792

    (另有一样的题(编译优化):http://210.33.19.103/contest/982/problem/5

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 #include<set>
     6 using namespace std;
     7 #define fi first
     8 #define se second
     9 #define mp make_pair
    10 #define pb push_back
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 typedef pair<ll,int> pli;
    14 struct E
    15 {
    16     int nxt,pre;ll d;
    17 }e[500100];
    18 int a[500100];
    19 int n,m;
    20 set<pli> s;
    21 set<pli>::iterator i1;
    22 ll an;
    23 int main()
    24 {
    25     int i,y;ll x;pli t;
    26     scanf("%d%d",&n,&m);
    27     if(m>n/2)
    28     {
    29         puts("Error!");
    30         return 0;
    31     }
    32     for(i=1;i<=n;i++)    scanf("%d",&a[i]);
    33     for(i=1;i<=n;i++)
    34     {
    35         e[i].nxt=i+1;
    36         e[i].pre=i-1;
    37         e[i].d=a[i];
    38         s.insert(mp(e[i].d,i));
    39     }
    40     e[n].nxt=1;e[1].pre=n;
    41     for(i=1;i<=m;i++)
    42     {
    43         i1=s.end();--i1;
    44         t=*i1;s.erase(i1);
    45         x=t.fi;y=t.se;
    46         an+=x;
    47         x=-x;
    48         x+=e[e[y].pre].d;x+=e[e[y].nxt].d;
    49         s.erase(mp(e[e[y].pre].d,e[y].pre));
    50         s.erase(mp(e[e[y].nxt].d,e[y].nxt));
    51         e[y].pre=e[e[y].pre].pre;e[e[y].pre].nxt=y;
    52         e[y].nxt=e[e[y].nxt].nxt;e[e[y].nxt].pre=y;
    53         e[y].d=x;
    54         s.insert(mp(e[y].d,y));
    55     }
    56     printf("%lld",an);
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    Silverlight OA系统(Silverlight办公自动化系统)
    Silverlight 3把多点触摸带进Web世界
    风云的银光志Silverlight4.0教程之使用CompositeTransform复合变形特效实现倒影
    最近团队完成的Silverlight 在线棋牌网络游戏
    Silverlight 3 多点触摸功能在Windows 7 中的应用
    风云的银光志Silverlight4.0教程之遍历访问客户端用户的本地文件
    网上Silverlight项目收集
    彻底解决Windowless=true情况下TextBox不能输入的问题
    相约微软大厦,Silverlight4.0技术分享线下活动明天下午正式开始!
    Silverlight WebOS(Web操作系统)
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9683773.html
Copyright © 2011-2022 走看看