題意:
給出一個DAG,每個點上有一定的價值p和數量w,給出一些轉換關系:a
i-1 a
i b
i ,即a
i-1可以兌換成b
i單位a
i ,然后問這些點的最大價值。
解法:
由于是DAG,可以用DP來解,dp[pos]=max{p[pos],dp[k]*rate[pos][k]},g[pos][k]=true
然后結果就是sum{dp[i]*w[i]}
這次第一次參加regional,fzu現場賽時候各種手殘腦殘,N個能夠秒的題都沒去看。甚可惜。。。回來看了下題目都不是多困難的,做個5題沒問題的說。。。哎,明年再一雪恥辱吧。。
代碼:
1
# include <cstdio>
2
# include <vector>
3
using namespace std;
4
const int N=10005;
5
struct node
6

{
7
int nxt;
8
double rate;
9
node(int n,double r):nxt(n),rate(r)
{};
10
};
11
vector<node> g[N];
12
double p[N],w[N];
13
bool used[N];
14
int n;
15
void solve(int pos)
16

{
17
if(used[pos]) return;
18
used[pos]=true;
19
for(int i=0;i<g[pos].size();i++)
20
{
21
solve(g[pos][i].nxt);
22
if(g[pos][i].rate*p[g[pos][i].nxt]>p[pos]) p[pos]=g[pos][i].rate*p[g[pos][i].nxt];
23
}
24
}
25
int main()
26

{
27
while(true)
28
{
29
scanf("%d",&n);
30
if(!n) break;
31
for(int i=1;i<=n;i++)
32
{
33
scanf("%lf%lf",p+i,w+i);
34
g[i].clear();
35
used[i]=false;
36
}
37
int m;
38
scanf("%d",&m);
39
while(m--)
40
{
41
int k;
42
scanf("%d",&k);
43
int last,now;
44
scanf("%d",&last);
45
k--;
46
while(k--)
47
{
48
double r;
49
scanf("%lf%d",&r,&now);
50
g[last].push_back(node(now,r));
51
last=now;
52
}
53
}
54
for(int i=1;i<=n;i++)
55
solve(i);
56
double ans=0;
57
for(int i=1;i<=n;i++)
58
ans+=p[i]*w[i];
59
printf("%.2f\n",ans);
60
}
61
return 0;
62
}
63