MZ test17# NOIP模拟题 # T2 第2题 最优时间表(sche.pas/cpp) [key.DP]

来源:互联网 发布:qt5 socket编程 编辑:程序博客网 时间:2024/06/09 20:00

第2题 最优时间表(sche.pas/cpp)

 

【问题描述】

一台精密仪器的工作时间为 n 个时间单位。与仪器工作时间同步进行若干仪器维修程序。一旦启动维修程序,仪器必须进入维修程序。如果只有一个维修程序启动,则必须进入该维修程序。如果在同一时刻有多个维修程序,可任选进入其中的一个维修程序。维修程序必须从头开始,不能从中间插入。一个维修程序从第s个时间单位开始,持续t个时间单位,则该维修程序在第s+t-1个时间单位结束。为了提高仪器使用率,希望安排尽可能少的维修时间。

   编程任务:对于给定的维修程序时间表,编程计算最优时间表。

 

【输入数据】

第 1 行有2 个正整数n和 k(1≤n,k≤9999)。n表示仪器的工作时间单位;k是维修程序数。接下来的k行中,每行有2 个表示维修程序的整数s和 t,该维修程序从第s个时间单位开始,持续t个时间单位。

 

【输出数据】

最少维修时间。

 

【样例输入】sche.in

15 6

1 2

1 6

4 11

8 5

8 1

11 5

 

【样例输出】sche.out

11


#include "stdio.h"#include "stdlib.h"#define maxn 10000int n,k;int rec[maxn];bool used[maxn]={false};struct node{ int s,e;}p[maxn];struct node1{ int s,e,last;       }dat[maxn];int cmp(const void *a,const void *b){ node aa=*(node *)a; node bb=*(node *)b; return aa.s-bb.s;    }void init(){ int i,t,t1;     freopen("sche.in","r",stdin); freopen("sche.out","w",stdout); scanf("%d%d",&n,&k); for(i=0;i<k;i++)  {   scanf("%d %d",&dat[i].s,&dat[i].last);         dat[i].e=dat[i].s+dat[i].last-1;  } qsort(dat,k,sizeof(dat[1]),cmp);  for(i=0;i<=n;i++)  p[i].s=p[i].e=-1; t=-1; for(i=0;i<k;i++)  {   if(t!=dat[i].s)    {     t=dat[i].s;     p[t].s=i;    }     p[t].e=i;  } }int s(int a){ if(used[a])  return rec[a]; int i,t=10001,t1; if(p[a].s==-1&&p[a].e==-1)  {  if(a<n)   t=s(a+1);  if(a==n)   t=0;  } else  {  for(i=p[a].s;i<=p[a].e;i++)   if(dat[i].e<=n)     {    t1=dat[i].last;    if(dat[i].e<n)     t1+=s(dat[i].e+1);    if(t>t1)     t=t1;    }  }  used[a]=true;  rec[a]=t;  return t; }int main(){ init(); printf("%d",s(1));    }
p党:
type   act=record   st,ed:longint;   end;  var   a:array[0..10000]of act;   f:array[0..1000000]of longint;   n,i,j,k:longint;  procedure qsort(l,r:longint);  var   i,j,k:longint;   t:act;  begin   i:=l;j:=r;   k:=a[(l+r)shr 1].st;   repeat   while a[i].st<k do inc(i);   while a[j].st>k do dec(j);    ifi<=j then    begin     t:=a[i];a[i]:=a[j];a[j]:=t;     inc(i);dec(j);    end;   until i>j;   ifi<r then qsort(i,r);   ifj>l then qsort(l,j);  end;  function max(a,b:longint):longint;  begin   ifa<b then exit(b);   exit(a);  end;  begin   assign(input,'p318.in');reset(input);   assign(output,'p318.out');rewrite(output);   readln(n,k);   fori:=1 to k do   begin    readln(a[i].st,a[i].ed);   end;   qsort(1,k);   fillchar(f,sizeof(f),0);   fori:=n downto 1 do    ifi<>a[k].st then f[i]:=f[i+1]+1    else     while i=a[k].st do      begin       f[i]:=max(f[i],f[a[k].st+a[k].ed]);       dec(k);      end;   writeln(n-f[1]);   close(input);close(output);  end.  


 fori:=n downto 1 do    ifi<>a[k].st then f[i]:=f[i+1]+1    else     while i=a[k].st do      begin       f[i]:=max(f[i],f[a[k].st+a[k].ed]);       dec(k);      end;  


上面Pascal代码的C++翻译版本(部分)

for (int i=n;i>=1;i--){   if (i!=a[k].st) f[i]=f[i+1]+1;   else    while (i==a[k].st)   {      f[i]=max(f[i],f[a[k].st+a[k].ed];      k--;   }}

[translated by CH.]


c++完整翻译版本

#include <cstdio>#include <algorithm>#include <cstring>#include <iostream>using namespace std;struct act{   int st,ed;}a[10005];int f[1000000],n,i,j,k;bool cmp(act a,act b){   return a.st<b.st;}int main(){   cin>>n>>k;   for (i=1;i<=k;i++)   scanf("%d%d",&a[i].st,&a[i].ed);   sort(a+1,a+1+k,cmp);   memset(f,0,sizeof(f));   for (int i=n;i>=1;i--)   {      if (i!=a[k].st) f[i]=f[i+1]+1;      else       while (i==a[k].st)      {          f[i]=max(f[i],f[a[k].st+a[k].ed]);          k--;       }    }    printf("%d",n-f[1]);}


#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>using namespace std;int n,k;struct cd{int l,r,len;}e[10001];bool cmp(cd A,cd B){//if(A.l==B.l)//return A.len<B.len;//elsereturn A.l<B.l;}int dp[10010];int main(){//#define LOC#ifdef LOCfreopen("sche.in","r",stdin);freopen("sche.out","w",stdout);#endifscanf("%d%d",&n,&k);int s,t;for(int i=1;i<=k;i++){scanf("%d%d",&e[i].l,&e[i].len);//e[i].len=e[i].r-e[i].l+1;e[i].r=e[i].l+e[i].len-1;}sort(e+1,e+1+k,cmp);for (int i=n;i>=1;i--)  {     if (i!=e[k].l) dp[i]=dp[i+1]+1;     else      while (i==e[k].l)     {        dp[i]=max(dp[i],dp[e[k].l+e[k].len]);        k--;     }  }     cout<<n-dp[1]; return 0;}


搜索[by.ZK]

#include<cstdio>#include<algorithm>#include<cstring>#define inf 0x3f3f3f3fusing namespace std;int n,k,h[10000],ans=inf,vis[10000],rec[10000];struct Prog{int progs,progt,t;}p[10000];bool cmp(Prog a,Prog b){if(a.progs==b.progs)return a.progt < b.progt;return a.progs<b.progs;}int dfs(int t){if(vis[t])return rec[t];if(!h[t]){if(t<n)dfs(t+1);elsereturn 0;}else{int m,r=inf;for(int i=1;i<=k;i++)if(p[i].progs==t){m=i;break;}while(p[m].progs==t){r=min(r,p[m].t+dfs(p[m].progt+1));m++;}vis[t]=1;rec[t]=r;return r;}}int main(){freopen("sche.in","r",stdin);freopen("sche.out","w",stdout);scanf("%d%d",&n,&k);for(int i=1;i<=k;i++){scanf("%d%d",&p[i].progs,&p[i].t);p[i].progt=p[i].progs+p[i].t-1;h[p[i].progs]=1;}sort(p+1,p+1+k,cmp);ans=dfs(1);printf("%d",ans);return 0;}


补充 本题转化为图论的解法。[by.GLK]

#include<cstdio>#include<algorithm>#include<cstring>#include<queue>using namespace std;struct edge{int to,w;edge *next;};const int maxn = 9999 + 10;edge* head[maxn];void adde(const int& a,const int& b,const int& c){edge* ne = new edge();ne->to = b;ne->w = c;ne->next = head[a];head[a] = ne;}struct point{int t,type;bool operator < (const point& a)const{if(t==a.t) return type < a.type;return t < a.t;}};point P[maxn<<1];int dis[maxn];bool inq[maxn];void SPFA(){memset(dis,127,sizeof(dis));dis[P[0].t] = 0;queue<int>q;q.push(P[0].t);int p;while(!q.empty()){p = q.front();q.pop();inq[p] = false;for(edge* i = head[p];i!=NULL;i = i->next){if(dis[i->to] <= dis[p] + i->w) continue;dis[i->to] = dis[p] + i->w;if(!inq[i->to]){q.push(i->to);inq[i->to] = true;}}}}int main(){freopen("sche.in","r",stdin);freopen("sche.out","w",stdout);int n,k,a,b;scanf("%d%d",&n,&k);for(int i = 0;i < k;++i){scanf("%d%d",&a,&b);P[i<<1] = (point){a,1};P[i<<1|1] = (point){a+b,0};adde(a,a+b,b);}P[k<<1] = (point){n+1,1};std::sort(P,P+(k<<1));for(int i = 0,j = 0;i <= (k<<1);++i){if(P[i].type) continue;for(j = i + 1;j <= (k<<1);++j)if(P[j].type&&P[j].t >= P[i].t)break;adde(P[i].t,P[j].t,0);}SPFA();printf("%d",dis[n+1]);return 0;}



1 0
原创粉丝点击