ACM-ICPC 2018 焦作賽區網路預賽 K Transport Ship(多重揹包)
阿新 • • 發佈:2018-12-12
題目大意:n個船,每個船載重vi,數量2^ci-1,問載重正好是s有幾種情況
題目思路:由於固定了數量,所以很容易想到是多重揹包。問的是方案數,所以設dp[0]為1,剩下來初始化為0,然後上去跑多重揹包板子就過了
以下是程式碼:
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) #define per(i,a,b) for(int i=a;i>=b;i--) const int MOD = 1e9+7; const int MAXN = 1e4+5; struct node{ int v,c; }a[30]; ll dp[MAXN]; int main(){ int n,q,s; int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&q); rep(i,1,n)scanf("%d%d",&a[i].v,&a[i].c),a[i].c=(1<<a[i].c)-1; memset(dp,0,sizeof(dp)); dp[0]=1; rep(i,1,n){ if(a[i].c*a[i].v>=MAXN){ rep(j,a[i].v,MAXN){ dp[j]=(dp[j]+dp[j-a[i].v])%MOD; } } else{ int k=1,temp=a[i].c; while(k<temp){ per(j,MAXN,k*a[i].v){ dp[j]=(dp[j]+dp[j-k*a[i].v])%MOD; } temp-=k; k<<=1; } per(j,MAXN,temp*a[i].v){ dp[j]=(dp[j]+dp[j-temp*a[i].v])%MOD; } } } rep(i,1,q){ scanf("%d",&s); printf("%lld\n",dp[s]); } } return 0; }