Http://codeforces.com/problemset/problem/283/C
At the beginning, look at the sample do not understand, why 5 * A1 + A3 do not? It's 17.
The original is, the topic requires the number of coins A3 > A4 > A2, then, if not selected, is not legal. is 0, 0, 0 This is not legal, because a3 = A4.
Then you know, A3 at least choose two.
So how do you maintain this relationship? , the idea is to rely on the backpack, the number of A3 need more than A4, you can turn A4 that item into A3 + A4
Then each time the choice, it implicitly chose a piece of A3. Of course, the premise is that at least 2 pieces of A3, 1 pieces of A4, 0 pieces of A2 are selected.
Then take the required Val minus what must be chosen, and make a complete backpack.
#include <cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<assert.h>#defineIOS Ios::sync_with_stdio (False)using namespacestd;#defineINF (0X3F3F3F3F)typedefLong Long intLL; #include<iostream>#include<sstream>#include<vector>#include<Set>#include<map>#include<queue>#include<string>#include<bitset>Const intMAXN = -+ -;intFA[MAXN], A[MAXN];BOOL out[MAXN];intN, Q, Val;structNode {intu, V, tonext;} E[MAXN*2];intFIRST[MAXN];intnum;voidAddintUintv) {++num; E[NUM].U=u; E[NUM].V=v; E[num].tonext=First[u]; First[u]=num;}BOOLVIS[MAXN];voidDfsintcur) { for(inti = first[cur]; I i =E[i].tonext) { intv =e[i].v; if(Vis[v]) {cout<<0<<Endl; Exit (0); } Vis[v]=true; DFS (v); VIS[V]=false; }}voidCalcintCurintti) { if(cur = =0)return; Val-= a[cur] *ti; if(Val <0) {//cannot equalcout <<0<<Endl; Exit (0); } calc (Fa[cur], ti+1); A[cur]+=A[fa[cur]];}intdp[100000+ -];Const intMOD = 1e9 +7;voidWork () {cin>> N >> Q >>Val; for(inti =1; I <= N; ++i) {cin>>A[i]; } for(inti =1; I <= Q; ++i) {intu, v; CIN>> u >>v; FA[V]=u; out[U] =true; Add (U, v); } for(inti =1; I <= N; ++i) {//if (vis[i]) continue;Vis[i] =true; DFS (i); Vis[i]=false; } for(inti =1; I <= N; ++i) {if( out[i])Continue; Calc (i,0); } dp[0] =1; for(inti =1; I <= N; ++i) { for(intj = A[i]; J <= Val; ++j) {Dp[j]+ = Dp[j-A[i]]; if(Dp[j] >= MOD) dp[j]%=MOD; }} cout<< Dp[val] <<Endl;}intMain () {#ifdef local freopen ("Data.txt","R", stdin);//freopen ("Data.txt", "w", stdout);#endifIOS; Work (); return 0;}
View Code
C. Coin troubles Dependent backpack + Complete backpack variants