【多重背包+二进制优化】ACM-ICPC 2018 焦作赛区网络预赛 - K. Transport Ship

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monochrome00/article/details/82718400

题目链接<https://nanti.jisuanke.com/t/31720>


题意:

给出若干个船,每个船都有V[i]的容量,和2^{C[i]}的数量。有Q次询问,给出一定体积的货物,问你恰好装满的方案数量。


题解:

很明显的多重背包,但是要加上二进制优化。

所谓二进制优化就是把数量拆成2^0,2^1,2^2,2^3.....2^(k-1) , c-2^k+1,使得算法复杂度降为log级别。

由于题目的数量是2的幂次,拆出来的数是没有最后一项的。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+7;
const ll mod=1e9+7;
ll v[N],c[N],dp[N],n,m,x;
int main(){
    ll t;
    scanf("%lld",&t);
    while(t--){
        scanf("%lld%lld",&n,&m);
        memset(dp,0,sizeof(dp));
        for(ll i=1;i<=n;i++)
            scanf("%lld%lld",&v[i],&c[i]);
        dp[0]=1;
        for(ll i=1;i<=n;i++){
            ll tmp=1;
            for(ll j=0;j<c[i];j++){
                for(ll k=10000;k>=tmp*v[i];k--){
                    dp[k]=(dp[k]+dp[k-tmp*v[i]])%mod;
                }
                tmp<<=1;
            }
        }
        while(m--){
            scanf("%lld",&x);
            printf("%lld\n",dp[x]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/monochrome00/article/details/82718400
今日推荐