• 洛谷 P2662 牛场围栏


    做法是这样的:

    首先暴力把所有可能的边长搞出来。。(当然<=0的不要)

    排序边长+去重,

    当且仅当可行边长里面有1时,任何长度都能取到,输出-1

    当且仅当所有可行边长的gcd大于1时,不能取到的长度没有上限,输出-1

    其他情况,一定有解;设最短的可行边长为x

    将所有可行边长按除以x的余数分类,一类建立一个点(除以x的余数为u,则建立u点)

    对于每一个可行边长y,对于每一个点u,从点u向点(u+y)%x连一条长度为y的边

    可以发现从0号点向任意点u的最短路长度(dijkstra跑出来)(设为d),就是所有能取到的总长度中,除以x的余数为u的之中,最短的;且这一类(指除以x的余数为u的长度)中,所有大于d的长度也都能取到(只要加上一些长度为x的边就行了);因此,d-x就不能取到了

    那么最大的不能取到的就是所有“d-x”的最大值(等于“所有d的最大值”-x)

    严谨一些的证明要比noip那道复杂很多啊。。根本不会,以后再说吧

    https://blog.csdn.net/Timsei/article/details/63254318

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 #include<queue>
     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 int n,m;
    15 int tt[300100];
    16 priority_queue<pii,vector<pii>,greater<pii> > q;
    17 int d[3010],mm=-0x3f3f3f3f;
    18 bool vis[3010];
    19 int main()
    20 {
    21     int i,j,u,v;pii t;
    22     scanf("%d%d",&n,&m);
    23     for(i=1;i<=n;i++)
    24     {
    25         scanf("%d",&u);
    26         for(j=0;j<=m;j++)
    27         {
    28             if(u-j<=0)    break;
    29             tt[++tt[0]]=u-j;
    30         }
    31     }
    32     sort(tt+1,tt+tt[0]+1);tt[0]=unique(tt+1,tt+tt[0]+1)-tt-1;
    33     if(tt[1]==1)
    34     {
    35         puts("-1");
    36         return 0;
    37     }
    38     int g=tt[1];
    39     for(i=2;i<=tt[0];i++)    g=__gcd(g,tt[i]);
    40     if(g!=1)
    41     {
    42         puts("-1");
    43         return 0;
    44     }
    45     memset(d,0x3f,sizeof(d));
    46     q.push(mp(0,0));d[0]=0;
    47     while(!q.empty())
    48     {
    49         t=q.top();q.pop();
    50         u=t.se;
    51         if(vis[u])    continue;
    52         vis[u]=1;
    53         for(i=1;i<=tt[0];i++)
    54         {
    55             v=(u+tt[i])%tt[1];
    56             //printf("%d %d
    ",u,v);
    57             if(d[v]>d[u]+tt[i])
    58             {
    59                 d[v]=d[u]+tt[i];
    60                 q.push(mp(d[v],v));
    61             }
    62         }
    63     }
    64     for(i=0;i<tt[1];i++)    mm=max(mm,d[i]);
    65     printf("%d",mm-tt[1]);
    66     //for(i=0;i<tt[1];i++)    printf("%d %d
    ",i,d[i]);
    67     return 0;
    68 }
  • 相关阅读:
    PHP+MYSQL不错的环境架设软件
    ASV2011(Action Script Viewer)免费升级
    Win2003证书服务配置/客户端(服务端)证书申请/IIS站点SSL设置
    Entity FrameWork 4 PoCo使用
    使用Forms Authentication实现用户注册、登录
    验证数字的正则表达式集
    web.config/app.config敏感数据加/解密的二种方法
    如何创建一个标准的Windows服务
    抛弃WebService 在.NET4中用jQuery调用WCF
    EF 中调用带输出参数的存储过程
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9410465.html
Copyright © 2020-2023  润新知