codeforces 283C

题解:

考虑这个东西是带约束条件的完全背包

想办法把xi>xj的约束条件消掉

那么我们把限制条件(xi > xj)看成边 i -> j,连成有向图

发现这个有向图是一堆环和链

有环显然就GG了,然后我们只要考虑全是链的情况

考虑全是链,那么我们消掉约束条件就是每次原有权值加上所有前驱的权值

然后就是一个不带约束条件的完全背包

但是。。。除了出度为0的点意外其他点不能不选

那么就减去不选的方案数就行了

 1 #include<bits/stdc++.h>
 2 #define maxn 305
 3 #define maxt 100005 
 4 #define ll long long
 5 using namespace std;
 6 const ll mod = 1000000007;
 7 int n,q,t;
 8 int a[maxn];
 9 int pre[maxn],vis[maxn];
10 bool h[maxn],hx[maxn];
11 ll dp[maxt],f[maxt];
12 int main()
13 {
14     scanf("%d%d%d",&n,&q,&t);
15     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
16     for(int i=1;i<=n;++i)h[i]=1,hx[i]=1;
17     for(int i=1;i<=q;++i)
18     {
19         int b,c;
20         scanf("%d%d",&b,&c);
21         pre[b]=c;h[c]=0;hx[b]=0;
22     }
23     for(int i=1;i<=n;++i)if(h[i])
24         for(int x=i;x;x=pre[x])a[pre[x]]+=a[x],vis[x]=1;
25     for(int i=1;i<=n;++i)if(!vis[i])
26     {
27         puts("0");exit(0);
28     }
29     dp[0]=1;
30     for(int i=1;i<=n;++i)
31     {
32         if(hx[i])
33         {
34             for(int j=a[i];j<=t;++j)dp[j]=(dp[j]+dp[j-a[i]])%mod;
35         }
36         else
37         {
38             memcpy(f,dp,sizeof(f));
39             for(int j=a[i];j<=t;++j)dp[j]=(dp[j]+dp[j-a[i]])%mod;
40             for(int j=0;j<=t;++j)dp[j]=(dp[j]-f[j]+mod)%mod;
41         }
42     }
43     printf("%I64d\n",dp[t]);
44     return 0;
45 }
View Code

 

posted @ 2019-03-30 17:49  幽蝶  阅读(229)  评论(0编辑  收藏  举报