CodeForces #174.div2.problem E-----(DP)
来源:互联网 发布:机动战士z高达评价知乎 编辑:程序博客网 时间:2024/05/22 08:19
In the Isle of Guernsey there are n different types of coins. For each i (1 ≤ i ≤ n), coin of type i is worth ai cents. It is possible that ai = aj for some i and j (i ≠ j).
Bessie has some set of these coins totaling t cents. She tells Jessie q pairs of integers. For each i (1 ≤ i ≤ q), the pair bi, ci tells Jessie that Bessie has a strictly greater number of coins of type bi than coins of type ci. It is known that all bi are distinct and all ci are distinct.
Help Jessie find the number of possible combinations of coins Bessie could have. Two combinations are considered different if there is some i (1 ≤ i ≤ n), such that the number of coins Bessie has of type i is different in the two combinations. Since the answer can be very large, output it modulo 1000000007 (109 + 7).
If there are no possible combinations of coins totaling t cents that satisfy Bessie's conditions, output 0.
The first line contains three space-separated integers, n, q and t (1 ≤ n ≤ 300; 0 ≤ q ≤ n; 1 ≤ t ≤ 105). The second line contains nspace separated integers, a1, a2, ..., an (1 ≤ ai ≤ 105). The next q lines each contain two distinct space-separated integers, bi and ci(1 ≤ bi, ci ≤ n; bi ≠ ci).
It's guaranteed that all bi are distinct and all ci are distinct.
A single integer, the number of valid coin combinations that Bessie could have, modulo 1000000007 (109 + 7).
4 2 17
3 1 2 5
4 2
3 4
3
3 2 6
3 1 1
1 2
2 3
0
3 2 10
1 2 3
1 2
2 1
0
For the first sample, the following 3 combinations give a total of 17 cents and satisfy the given conditions: {0 of type 1, 1 of type 2, 3 of type 3, 2 of type 4}, {0, 0, 6, 1}, {2, 0, 3, 1}.
No other combinations exist. Note that even though 4 occurs in both bi and ci, the problem conditions are still satisfied because all biare distinct and all ci are distinct.
思路:非常经典的背包问题。首先,题目给出了若干种硬币的数量大小关系,假设第 i 种硬币的数量为 ni, 若给出的条件是 ni > nj, nj > nk,(i != j, j !=k, i != k),说明在进行背包的时候, i 的数量必须比 j大,j的数量要比 k 大。这就是图论中的拓扑排序了,找出满足条件的这样一条大小关系(a1>a2>a3>...>an),构造新硬币 a1,a1+a2,a1+a2+a3,...,a1+a2+..+an,然后把a1到an的旧硬币去掉,最后对新硬币进行完全背包即可。然而题目中给出的大小关系可能是矛盾的,也可能不止一条大小关系,所谓矛盾也就是拓扑排序时有环,这样的话直接退出,因为没有满足的条件。对于多条关系,构造出所有的大小关系,对于这些关系,分别把初始容量 t -(a1+(a1+a2)+(a1+a2+a3)+...+(a1+a2+a3+...+an-1));这样的话,不管以后怎么取,都能保证大小关系是满足的(a1有n-1个,a2有n-2个....,而(a1+a2+...+an不是必须的,因为旧硬币中an可有可无)。当然,如果t在减去这些必须满足的大小关系后,若t < 0,说明也是无法满足条件的。DP的时候,初始化dp[0]=1,其余为0,其中dp[i]代表容量为 i 时的满足要求的最大个数。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #define MAX 100007 7 #define INF 1000000007 8 #define SIZE 330 9 10 using namespace std; 11 12 int dp[MAX]; 13 int deg[SIZE],son[SIZE]; 14 bool cnt[SIZE][SIZE]; 15 int coin[SIZE],seq[SIZE]; 16 int n,q,t,index; 17 18 void init() 19 { 20 for(int i=0; i<=n; i++) 21 { 22 deg[i] = 0; 23 seq[i] = 0; 24 son[i] = 0; 25 for(int j=0; j<=n; j++) 26 cnt[i][j] = false; 27 } 28 } 29 30 bool judge() //拓扑排序 31 { 32 queue <int> Q; 33 for(int i=1; i<=n; i++) 34 { 35 if(!deg[i]) 36 { 37 Q.push(i); 38 seq[i] = coin[i]; 39 if(son[i]) //只有在有比他数量小的硬币的存在时,才要减掉,因为他的数量必须比后面那个大---(2) 40 t -= seq[i]; 41 } 42 } 43 int num = n; 44 while(!Q.empty()) 45 { 46 int cur = Q.front(); 47 Q.pop(); 48 num --; 49 for(int i=1; i<=n; i++) 50 { 51 if(cnt[cur][i]) 52 { 53 -- deg[i]; 54 if(!deg[i]) 55 { 56 Q.push(i); 57 seq[i] = seq[cur] + coin[i]; 58 if(seq[i]>100000) //防止后面数组越界---(1) 59 seq[i] = 100001; 60 if(son[i]) //(2) 61 t -= seq[i]; 62 } 63 } 64 } 65 } 66 if(num) 67 return false; 68 return true; 69 } 70 71 int main() 72 { 73 scanf("%d %d %d",&n,&q,&t); 74 init(); 75 for(int i=1; i<=n; i++) 76 scanf("%d",&coin[i]); 77 for(int i=1; i<=q; i++) 78 { 79 int st,ed; 80 scanf("%d %d",&st,&ed); 81 cnt[st][ed] = true; 82 son[st] = ed; 83 deg[ed] ++; 84 } 85 bool check = judge(); 86 if(!check || t < 0) 87 printf("0\n"); 88 else 89 { 90 memset(dp,0,sizeof(dp)); 91 dp[0] = 1; 92 for(int i=1; i<=n; i++) 93 { 94 for(int j=0; j<=(t-seq[i]); j++) 95 dp[j+seq[i]] = (dp[j+seq[i]]+dp[j])%INF; //如果没有(1),而 i 又是数量最少的那个,会出现数组越界 96 } 97 printf("%d\n",dp[t]); 98 } 99 return 0;100 }
- CodeForces #174.div2.problem E-----(DP)
- CodeForces #187.div2.problem E
- CodeForces #174.div2.problem C
- codeforces 713C(Round #371 Div2 E) Sonya and Problem Wihtout a Legend Dp + 前缀 +离散化
- codeforces 361 div2 E. Mike and Geometry Problem
- DP Codeforces Round 401#div2 E.Hanoi Factory
- Codeforces #163 Div2 E
- codeforces 250 div2 E
- codeforces 171 div2 C&E
- codeforces 181 div2 C&E
- Codeforces Round#99 E(Div2)
- codeforces div2 round#230 E
- codeforces #284 div2 ABCD*E*
- codeforces 292 div2 E【RE】
- codeforces Round 377 Div2 E
- CodeForces #181.div2.problem C
- codeforces 713C(Round #371 Div2 E) Sonya and Problem Wihtout a Legend ★ ★
- [DP] Codeforces #714E. Sonya and Problem Wihtout a Legend
- POJ 2653 Pick-up sticks (判断线段相交)
- HDU 1558 Segment set (并查集+线段相交)
- POJ 2392 Space Elevator (多重背包问题)
- POJ 1014 Dividing (多重背包问题)
- CodeForces #174.div2.problem C
- CodeForces #174.div2.problem E-----(DP)
- HDU 1160 FatMouse's Speed (最长上升子序列+记录路径)
- HDU 1561 The more,The Better (树形DP+有依赖的背包问题)
- HDU 4341 Gold miner (分组背包问题)
- POJ 3260 The Fewest Coins (混合背包--多重背包+完全背包)
- POJ 2127 Greatest Common Increasing Subsequence (最长公共上升子序列+记录路径)
- HDU 1011 Starship Troopers (树形DP+背包)
- HDU 3449 Consumer (依赖背包)
- HDU 3033 I love sneakers! (分组背包)