Giroro制造武器

Giroro制造武器

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 12   Accepted Submission(s) : 4
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

Problem Description

自从keroro变成猩猩之后,giroro觉得这简直就是个耻辱。于是他决定自己制造武器去秒了毒蛇的基地!
制造一件武器是一件非常麻烦的 事情,例如制造一把刀:首先需要做好刀柄和刀刃,然后才能把刀基本做出来,要完整做出一把刀,还需要做出刀套。也就是说,在进行某道工序前,需要先完成某 些其他的工序。而且某道工序也有他制作的时间,虽然giroro有惊人的毅力(也就是说你可以认为giroro可以在同一个时间内进行无数道工序),但是 制作一个武器还是有它的最短时间的!
现在great_dragon_master已经把同一个武器的工序编好号,而且给出各道工序的时间,以及它们之间的先后关系。PS:如果说没有给出某两个工序的先后关系,也就是谁先做也没所谓,或者可以同时做,反正giroro是可以的。
giroro命令你算出每个武器最少的完成时间!
ps:保证这个武器可以制造出来,而且保证编号为n的工序是这个武器的最后一道工序。

Input

一个整数T(T<=1000),表示接下来又多少个武器需要制作。
接下来的T组:
每组的第一行两个整数n(1<=n<=100)和m(0<=m<=1000)分别表示这个武器的工序个数和工序关系的个数。
第二行有n个数,a[i]表示第i道工序所需要的时间(1<=a[i]<=100)。
接下来m行,每行两个数,x y(1<=x,y<=n),表示编号为y的工序开始之前,编号为x的工序必须完成。
请使用scanf代替cin来避免超时

Output

对于每个武器,输出其最少所需要的完成时间。

Sample Input

1
4 4
1 1 1 1
1 2
1 3
2 4
3 4

Sample Output

3

广工暑假培训选拔赛的题目,用树状dp,当时 不会,但想到了一条公式dp[n]=dp[n的前提]+t[n]代表完成n的时间。
然后写了个dpit(n)函数来找寻n的时间,实际上貌似是用了dfs后回溯dp选取,具体要看程序来了解了。
dpit(x)的原理就是不断寻找的前提,如果他又前提k就dpit(k)来找k的时间,知道某个已经被查找过或者是没有前提的,就return回来。
View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<stdlib.h>
 5 #define max(a,b) a>b?a:b
 6 #define min(a,b) a>b?b:a
 7 #define INF     0x3f3f3f3f
 8 #define Maxin 10000
 9 int fang[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
10 int s[112][112],dp[112];
11 int t[111],ans;
12 int n,m;
13 
14 int dpit(int k)
15 {
16     int x;
17     if(dp[k]!=0)
18         return dp[k];
19 
20     for(x=1;x<=n;x++)
21         if(s[x][k])
22            dp[k]=max(dp[k],dpit(x));
23  
24         dp[k]+=t[k];
25         return dp[k];
26 }
27 
28 int main()
29 {
30     int T;
31     scanf("%d",&T);
32     while(T--)
33     {
34         int x,y;
35         ans=0;
36         memset(dp,0,sizeof(dp));
37         memset(s,0,sizeof(s));
38         scanf("%d%d",&n,&m);
39         for(x=1;x<=n;x++)
40             scanf("%d",&t[x]);
41         for(x=0;x<m;x++)
42         {
43             int i,j;
44             scanf("%d%d",&i,&j);
45             s[i][j]=1;
46         }
47 
48         for(x=1;x<=n;x++)
49                 dp[x]=dpit(x);
50 
51         for(x=1;x<=n;x++)
52             if(ans<dp[x])
53                 ans=dp[x];
54         printf("%d\n",ans);
55     }
56     return 0;
57 }

 



转载于:https://www.cnblogs.com/usp10/archive/2012/06/11/2545463.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值