• 9.22考试 crf的军训 题解


      做这道题时由于第一道题太水了,第一反应是NOIP T2级别的题,需要拿上70~100的分,然后就开始分析,当然最后事实证明我错了……

      这道题当时首先联想到了 NOIP2016愤怒的小鸟 当然,数据范围不允许,但是我当时只是为了先拿到小数据的分数,所以先没考虑数据范围,在这里简单提一下:首先我先枚举了每一个状态,然后判断这个状态中的书是否能连在一起,然后就是一个2^(2*n)的转移,好吧,我承认,不是正宗的愤怒的小鸟打法,是当时集中生智编出来的,但是对于n<=10的复杂度还是够用的。

      然后对于小于80(我自己假定的一个数据范围)打了一个小爆搜,挂了。

      对于大于80的,也就是对应的正解部分,我首先想到的是贪心,然而被我自己rand出来的数据和状压一对比卡掉了,然后以为是动归,想了半天也没写出转移方程,于是也跪了,然后就开始往图论那里想,却一无所获。但是由于前一天刚刚看完《骗分导论》,想着万一有一些点仁义的不去卡我贪心呢?于是就把贪心交了上去,结果全WA了,拿到数据后输出了贪心答案-2得了60分,事后想一想也是,贪心一定比正确答案只多不少,减去一些数可能就是正解。但当时谁能想到呢?


                       蒟蒻与正解的分割线                      


      现在我来说正解,二分图最小路径(链)覆盖,由于造数据的标程有误,我就只说最正确的了(在此鸣谢撸串神的发现)。

      我们在二分图上跑最小链覆盖有一个巨大的前提:这个图一定是DAG,然而此题由于是要求“不超过”,所以会有两个规格一模一样的书之间有环,不过由于两本相同的书一定可以放在一起,所以我们只要把他们缩一下就行。

      然后由于最小链覆盖=n-最大匹配,所以我们只要向能放在他之后的点建边即可,然后就是最大匹配了。

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 #include<algorithm>
     7 #include<cmath>
     8 #include<map>
     9 #include<vector>
    10 #define N 305
    11 using namespace std;
    12 int n;
    13 struct no
    14 {
    15     int x,y;
    16 }node[N],node2[N];
    17 int px(no a,no b)
    18 {
    19     if(a.x==b.x)return a.y<b.y;
    20     return a.x<b.x;
    21 }
    22 struct ro
    23 {
    24     int to,next;
    25 }road[N*N*10];
    26 int zz,a[N];
    27 void build(int x,int y)
    28 {
    29     zz++;
    30     road[zz].next=a[x];
    31     road[zz].to=y;
    32     a[x]=zz;
    33 }
    34 bool fw[N];
    35 int b[3*N];
    36 bool find(int x)
    37 {
    38     for(int i=a[x];i>0;i=road[i].next)
    39     {
    40         int y=road[i].to;
    41         if(!fw[y])
    42         {
    43             fw[y]=1;
    44             if(!b[y]||find(b[y]))
    45             {
    46                 b[y]=x;
    47                 return 1;
    48             }
    49         }
    50     }
    51     return 0;
    52 }
    53 int main()
    54 {
    55     scanf("%d",&n);
    56     for(int i=1;i<=n;i++)
    57     {
    58         scanf("%d%d",&node2[i].x,&node2[i].y);
    59     }
    60     sort(node2+1,node2+n+1,px);
    61     int zzh=0;
    62     for(int i=1;i<=n;i++)
    63     {
    64         if(node2[i].x!=node[zzh].y||node2[i].y!=node[zzh].y)
    65         {
    66             zzh++;
    67             node[zzh]=node2[i];
    68         }
    69     }
    70     n=zzh;
    71     for(int i=1;i<=n;i++)
    72     {
    73         for(int j=1;j<=n;j++)
    74         {
    75             if(i==j)continue;
    76             if(node[i].x<=node[j].x&&node[i].y<=node[j].y)
    77                 build(i,j);
    78         }
    79     }
    80     int ans=0;
    81     for(int i=1;i<=n;i++)
    82     {
    83         memset(fw,0,sizeof(fw));
    84         if(find(i))
    85             ans++;
    86 
    87     }
    88     printf("%d
    ",n-ans);
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    Intellij IDEA创建Maven Web项目<转>
    Spring事件监听Demo
    maven打包源码<转>
    枚举类转成json
    Java多线程编程中Future模式的详解<转>
    细数JDK里的设计模式<转>
    设计模式-观察者模式(下)<转>
    Sqlserver自定义函数Function
    sqlSQL2008如何创建定时作业
    JSON 序列化和反序列化——JavaScriptSerializer实现
  • 原文地址:https://www.cnblogs.com/liutianrui/p/7581857.html
Copyright © 2020-2023  润新知