codeforces 283C Coin Troubles (神级思维+判环+背包)

来源:互联网 发布:app软件大全 编辑:程序博客网 时间:2024/04/30 08:14

题意:

给出一些硬币的价值,然后给出一个人拥有的硬币价值,问能有多少种方法得到这种价值,但是还有p个限定条件,就是bi的价值要大于ci的价值。

题解:

神级的处理方法,如果要是限制条件满足,那么取m个ci肯定要去至少m个bi,那么我们把ci的价值加上bi的价值(假设bi-A,ci-B),那么现在ci的价值就是A+B,总价值要减去ai的价值即-A。然后就可以愉快的完全背包。

#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<map>using namespace std;typedef long long lld;const int oo=0x3f3f3f3f;const lld OO=1LL<<61;const int MOD=1000000007;lld dp[100005];int w[305];int father[305],ind[305];int n,Q,t;void init(){    memset(father,-1,sizeof father);    memset(ind,0,sizeof ind);}bool ok(){    while(Q--)    {        int pos=0;        for(int i=1;i<=n;i++)        {            if(father[i]!=-1&&ind[i]==0)            {                pos=i;                break;            }        }        if(pos==0)return false;        int pre=father[pos];        father[pos]=-1;        ind[pre]--;        w[pre]+=w[pos];        t-=w[pos];        if(t<0)return false;    }    return true;}void DP(){    memset(dp,0,sizeof dp);    dp[0]=1;    for(int i=1;i<=n;i++)    {        for(int j=w[i];j<=t;j++)        {            dp[j]=(dp[j]+dp[j-w[i]]+MOD)%MOD;        }    }    cout<<dp[t]<<endl;}int main(){    int u,v;    while(scanf("%d %d %d",&n,&Q,&t)!=EOF)    {        init();        for(int i=1;i<=n;i++)            scanf("%d",&w[i]);        for(int i=1;i<=Q;i++)        {            scanf("%d %d",&u,&v);            father[u]=v;            ind[v]++;        }        if(!ok())        {            puts("0");            continue;        }        DP();    }    return 0;}/**4 2 173 1 2 54 23 43 2 63 1 11 22 33 2 101 2 31 22 1*/




0 0
原创粉丝点击