zoukankan      html  css  js  c++  java
  • 牛场围栏

    题目背景

    小L通过泥萌的帮助,成功解决了二叉树的修改问题,并因此写了一篇论文,

    成功报送了叉院(羡慕不?)。勤奋又勤思的他在研究生时期成功转系,考入了北京大学光华管理学院!毕业后,凭着自己积累下的浓厚经济学与计算机学的基础,成功建设了一个现代化奶牛场!

    题目描述

    奶牛们十分聪明,于是在牛场建围栏时打算和小L斗智斗勇!小L有N种可以建造围栏的木料,长度分别是l1,l2 … lN,每种长度的木料无限。

    修建时,他将把所有选中的木料拼接在一起,因此围栏的长度就是他使用的木料长度之和。但是聪明的小L很快发现很多长度都是不能由这些木料长度相加得到的,于是决定在必要的时候把这些木料砍掉一部分以后再使用。

    不过由于小L比较节约,他给自己规定:任何一根木料最多只能削短M米。当然,每根木料削去的木料长度不需要都一样。不过由于测量工具太原始,小L只能准确的削去整数米的木料,因此,如果他有两种长度分别是7和11的木料,每根最多只能砍掉1米,那么实际上就有4种可以使用的木料长度,分别是6, 7,10, 11。        

    因为小L相信自己的奶牛举世无双,于是让他们自己设计围栏。奶牛们不愿意自己和同伴在游戏时受到围栏的限制,于是想刁难一下小L,希望小L的木料无论经过怎样的加工,长度之和都不可能得到他们设计的围栏总长度。不过小L知道,如果围栏的长度太小,小L很快就能发现它是不能修建好的。因此她希望得到你的帮助,找出无法修建的最大围栏长度。

    这一定难不倒聪明的你吧!如果你能帮小L解决这个问题,也许他会把最后的资产分给你1/8哦!

    输入输出格式

    输入格式:

    输入的第一行包含两个整数N,  M,分别表示木料的种类和每根木料削去的最大值。以下各行每行一个整数li(1< li< 3000),表示第i根木料的原始长度。

    输出格式:

    输出仅一行,包含一个整数,表示不能修建的最大围栏长度。如果任何长度的围栏都可以修建或者这个最大值不存在,输出-1。

    输入输出样例

    输入样例#1:
    2 1
    7 11
    输出样例#1:
    15

    说明

    40 % :1< N< 10,  0< M< 300

    100 % :1< N< 100,  0< M< 3000 

    分类讨论

    1、若木料可以取到1,无解

    2、若任意木料的gcd大于1,有无穷解

    3、若gcd(a,b)=1,则上限为ab-a-b

         证明:http://blog.csdn.net/archibaldyangfan/article/details/7637831

    然后此题变成水背包。。。听说还能用最短路。。。然而我并不会。。。

    const oo=9000010;maxn=3010;
    var f:array[0..oo] of boolean;
        temp,n,m,i,j,tot,mingcd:longint;
        a:array[0..maxn] of longint;
        bool:array[0..maxn] of boolean;
    
    procedure swap(var x,y:longint);
    var t:longint;
    begin
      t:=x;x:=y;y:=t;
    end;
    
    procedure gcd(a,b:longint);
    var r:longint;
    begin
      r:=a mod b;
      if r=0 then mingcd:=b else gcd(b,r);
    end;
    
    begin
    read(n,m);
    for i:=1 to n do
    begin
      read(a[i]);
      bool[a[i]]:=true;
    end;
    for i:=1 to n do
      for j:=1 to m do
      begin
        if a[i]-j<=0 then break;
        bool[a[i]-j]:=true;
      end;
    if bool[1] then
    begin
      write(-1);
      halt;
    end;
    tot:=0;
    for i:=1 to 3000 do
      if bool[i] then
      begin
        inc(tot);
        a[tot]:=i;
        if mingcd=0 then mingcd:=i else gcd(i,mingcd);
      end;
    if mingcd<>1 then
    begin
      write(-1);
      halt;
    end;
    i:=0;f[0]:=true;
    while true do
    begin
      inc(i);
      for j:=1 to tot do
      begin
        if a[j]>i then break;
        if f[i-a[j]] then
        begin
          f[i]:=true;
          break;
        end;
      end;
      if f[i]=false then temp:=0 else inc(temp);
      if temp=a[1] then
      begin
        write(i-temp);
        halt;
      end;
    end;
    end.
    View Code
  • 相关阅读:
    【转】IOS开发:[1]Xcode5界面入门
    【转】Xcode中的iOS模拟器(iOS Simulator)的介绍和使用心得
    特征选择
    EM算法
    算法之美--3.2.3 KMP算法
    算法之美--3.2.2 MP算法
    图像质量评价方法PSNR+SSIM&&评估指标SROCC,PLCC
    C/C++二进制读写png文件
    大津法---OTSU算法
    一些优秀的面试笔试总结
  • 原文地址:https://www.cnblogs.com/x1273011572/p/5894159.html
Copyright © 2011-2022 走看看