http://acm.hdu.edu.cn/showproblem.php?pid=2474
题意:有n个资源和m个进程,先给出一个n*m的资源分配表,再给出一个n*m的资源需求表,request[i][j]表示第j个进程还需要i中资源request[i][j]个。最后给出一个m数的序列,available[i]表示第i种资源可用的数目。问是否存在一个合适的进程序列使得n个进程都能执行完毕。
思路:比赛时先是纯模拟了一遍,傻X了,n<=50000。然后队友提示说弄两个队列,在当前队列里遍历进程,若当前进程可以执行就标记,否则就近进一个队列等待判断。结果TLE。
可以这么想,因为m<=3,可以将m种资源分别放在m个队列中,开始将n个进程每种资源的request放进对应优先队列中。一个进程要执行成功,要有m种资源,即该进程要出队m次,每出队一次,说明该资源可供当前进程使用。所以只需判断进程是否出队m次即可。
#include <iostream> #include <string> #include <cmath> #include <math.h> #include <queue> #include <algorithm> #include <stack> #include <vector> #include <string.h> #include <stdio.h> using namespace std; struct node { int id; int need; bool operator < (struct node tmp)const { return need < tmp.need; } }que[4][50010]; int n,m; int allo[4][50010]; int ava[4]; int outque[50010];//记录每个进程出队列的次数 int p[4]; bool solve() { int flag = 1; int i,j,k; int sum = 0; while(flag == 1) { flag = 0; for(i = 1; i <= m; i++) //从第一个队列开始枚举 { for( ; p[i] <= n; p[i]++) { if(ava[i] < que[i][p[i]].need) break; flag = 1; outque[ que[i][p[i]].id ]++; if(outque[ que[i][p[i]].id ] == m) //当出队次数等于m时,说明该进程可以执行 { sum++; for(j = 1; j <= m; j++) //更新vav[]。 ava[j] += allo[j][ que[i][p[i]].id ]; } } } } if(sum == n) return true; return false; } void debug() { for(int i = 1; i <= m; i++) { for(int j = 1; j <= n; j++) printf("i :%d need: %d ",que[i][j].id,que[i][j].need); printf("\n"); } } int main() { while(~scanf("%d %d",&n,&m)) { for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) scanf("%d",&allo[i][j]); for(int i = 1; i <= m; i++) { for(int j = 1; j <= n; j++) { que[i][j].id = j; scanf("%d",&que[i][j].need); //先把每个进程对应的m个资源放进队列 } } //debug(); for(int i = 1; i <= m; i++) { scanf("%d",&ava[i]); p[i] = 1; sort(que[i]+1,que[i]+1+n); //对每种资源按需求量升序排序 } //debug(); memset(outque,0,sizeof(outque)); if(solve()) printf("Yes\n"); else printf("No\n"); } return 0; }
hdu 2474 Process scheduling(模拟+队列),布布扣,bubuko.com
hdu 2474 Process scheduling(模拟+队列)
原文:http://blog.csdn.net/u013081425/article/details/24328729