JZOJ2017.08.07 C组

59 篇文章 0 订阅

T1

题目描述

最近,飞过海在OI总部总算弄了个小差,现在他又被调去了OI防卫部门来制造对付基德的工具。当然,这些工作是在OI总部内的机器上进行的,可是飞过海从来没有此经验,现在飞过海又接到了一批新的任务,现在他要编程来控制机器。已知机器一天工作N mins,当飞过海按动开始按钮的时候机器就开始运转。

现在OI总司给了K个生产目标,可是只有一台机器,所以总司希望知道最少机器能生产多少个零件(也就是最少工作多少分钟)。如果同时有许多的零件要加工,机器只能选择一个。但是一个零件任务是有时间限制的,也就是说,1个零件必须从P分开始,持续T分钟(好牵强的规定啊!)。

由于飞过海很忙,所以请你来编写一下这个程序吧!

思路:

其实题目是说求最大偷懒时间。
dp。
f[i]表示第i时段最大偷懒时间。

代码:

#include <stdio.h>
#include <iostream>
int n,k,m;
int a[100005],b[100005],f[11010005];
int main(){
    freopen("produce.in", "r", stdin);  
    freopen("produce.out", "w", stdout);  
    scanf("%d%d",&n,&k);
    for (int i=1;i<=k;++i) scanf("%d%d",&a[i],&b[i]);
    for (int i=n;i>=1;--i)
        if (a[k]!=i) f[i]=f[i+1]+1;
        else while (a[k]==i){
            f[i]=(f[i+b[k]]<f[i])?f[i]:f[i+b[k]];
            k--;
        }
    printf("%d",n-f[1]);
}

T2

题目描述

天网恢恢,疏而不漏,经过上一次的抓捕,OI总部终于获取了怪盗的特征!现在,我们需要在基德再次来之前就把他的特征送到超级大牛的手上,可惜超级大牛不在总部,所以飞过海必须尽快把资料送到大牛家里。已知OI总部到大牛家中间有n-2个城城市,为了尽快达到目的地,飞过海通过水晶球了解到OI总部到大牛家的路线图,图上显示了n个城之间的连接距离。

可是飞过海很忙,需要请你来帮忙编写一个程序。

思路:

最短路+统计路径,没啥好说的。。。。。

代码:

var a:array[-10..1010,-10..1010]of longint;
    b:array[-10..1010] of longint;
    flag:array[-10..1010]of boolean;
    w,x,n,i,j,min,minn:longint;
procedure print(x:longint);
begin
  if x=1 then begin write(x,' '); exit; end;
  print(b[x]);
  write(x,' ');
end;
begin
  assign(input,'city.in');
  assign(output,'city.out');
  reset(input);
  rewrite(output);
  read(n);
  for i:=1 to n do
    for j:=1 to n do
    begin
      read(a[i,j]);
      if a[i,j]=0 then a[i,j]:=maxlongint div 3;
    end;
  fillchar(flag,sizeof(flag),false);
  flag[1]:=true;
  minn:=1;
  for i:=1 to n do b[i]:=1;
  for x:=2 to n do
  begin
    min:=maxlongint div 3;
    for i:=2 to n do
    if (a[1,i]<min)and(flag[i]=false) then
    begin
      min:=a[1,i];
      minn:=i;
    end;
    flag[minn]:=true;
    for j:=1 to n do
    if (j<>minn) and (a[1,minn]+a[minn,j]<a[1,j]) and(flag[j]=false) then
    begin
      a[1,j]:=a[1,minn]+a[minn,j];
      b[j]:=minn;
    end;
  end;
  print(n);
  writeln;
  writeln(a[1,n]);
  close(input);
  close(output);
end.

T3

题目描述

现在,OI界出现了一位来无影去无踪的怪盗,那就是基德!曾经他盗窃了著名的Paris Sunshine,各位大牛为之震惊!所以,在这之后,许多大牛都废寝忘食,研究对付基德的有效办法,在这期间,为了防止基德再次来盗窃,OI总司令就决定派出OIER,来保护OI总部。现在你担任OI防御大队大队长,需要在OI总部里安排尽可能多的OI特制陷阱!原来OI总部是完全分离的两部分需要铺设特殊的管道才能到达OI总部。现在,OIER为了保卫总部,设计了许多许多的陷阱,让基德自投罗网。

现在有一份超级无敌大牛提供的宝贵规划资料,需要让你来部署。你的任务就是编写一个程序来实现这次规划

思路:

一边排序,一边求最长上升子序列。

代码:

uses math;
var a,b:array[0..500100] of int64;
    f:array[0..500100] of longint;
    x,y:int64;
    n,i,j,s:longint;
procedure qsort(l,r:longint);
var i,j,mid:longint;
begin
  if l>=r then exit;
  i:=l; j:=r; mid:=a[(i+j) div 2];
  repeat
    while a[i]<mid do inc(i);
    while a[j]>mid do dec(j);
    if i<=j then
    begin
      a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0];
      b[0]:=b[i]; b[i]:=b[j]; b[j]:=b[0];
      inc(i); dec(j);
    end;
  until i>=j;
  qsort(l,j);
  qsort(i,r);
end;
begin
  assign(input,'save.in');
  assign(output,'save.out');
  reset(input);
  rewrite(output);
  read(x,y);
  read(n);
  for i:=1 to n do read(a[i],b[i]);
  qsort(1,n);
  fillchar(f,sizeof(f),0);
  f[1]:=1; b[0]:=0;
  for i:=1 to n do
    for j:=0 to i-1 do
      if b[i]>=b[j] then f[i]:=max(f[j]+1,f[i]);
  for i:=1 to n do if f[i]>s then s:=f[i];
  write(s);
  close(input);
  close(output);
end.

T4

题目描述

OI总部最近得到可靠消息,近日来怪盗基德会再次来OI总部盗窃机密文件(因为是机密,所以不能透露),所以OIER得在怪盗基德来临之前就把文件备份。不过,正好今天OI总部停电了,所以就得人工抄写了。现在,OI总部内一共有M份资料和K个OIER(S),需要将每一份资料都备份一份,M份资料的页数不一定相同(有不同的,也有相同的)。

现在,你作为其中的一名OIER,把资料分配给OIER备份,由于人太多了,所以每一名OIER所分配到的资料都必须是连续顺序的,并且每一名OIER的备份速度是相同的。

你的任务就是让备份的时间最短,列出最短的方案。数据可能存在多个解,所以,当存在多个解时,让前面的人少备份。

思路:

二分答案,出后面开始做,保证后大于前。

代码:

var i,m,n,t:longint;
    ans,max,l,r:int64;
    a:array[1..1005] of longint;
procedure found;
var s,i:longint;
    mid:int64;
begin
  mid:=(l+r) div 2;
  s:=0; t:=0;
  for i:=n downto 1 do
  begin
    if a[i]>mid then
    begin
      l:=mid+1;
      exit;
    end;
    if t+a[i]>mid then
    begin
      s:=s+1;
      t:=a[i];
      if s=m then
      begin
        l:=mid+1;
        exit;
      end;
    end else t:=t+a[i];
  end;
  if s<m then
  begin
    if ans>mid then ans:=mid;
    r:=mid;
  end;
end;
procedure print(x:longint);
var i,p:longint;
begin
  if x=1 then
  begin
    writeln(1,' ',x);
    exit;
  end;
  p:=0;
  t:=a[x];
  for i:=x-1 downto 1 do
  if t+a[i]>ans then
  begin
    p:=i+1;
    break;
  end else t:=t+a[i];
  if (i=1)and(p=0) then
  begin
    writeln(1,' ',x);
    exit;
  end;
  print(p-1);
  writeln(p,' ',x);
end;
begin
  assign(input,'secret.in');
  assign(output,'secret.out');
  reset(input);
  rewrite(output);
  ans:=maxlongint;
  read(n,m);
  for i:=1 to n do
  begin
    read(a[i]);
    max:=max+a[i];
  end;
  l:=1;
  r:=max;
  while r<>l do found;
  t:=0;
  print(n);
  close(input);
  close(output);
end.
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值