1. 程式人生 > >ICPC 2018 焦作網路預賽 K. Transport Ship

ICPC 2018 焦作網路預賽 K. Transport Ship

題目意思

T組案例,第一行T,第二行兩個數字N,M,表示有N種船隻,M次詢問,接下來N行,每行兩個數字v[i],c[i],每種船隻的載貨量為v[i],每種船隻有2^c[i]-1種,有M次詢問,每次詢問給出一個數字s,問有多少種載貨方式填滿容量s。

樣例輸入 1 1 2 2 1 1 2 樣例輸出 0 1

解題思路

針對與每種船有2 ^ c[i]-1,可以想到任何一個數字都可以由2 ^ 0+2 ^ 1+2 ^ 2+…+2 ^ (c[i]-1)中的任意項組成,因此,可以將1,2,4,8,16 ,2^(c[i]-1)個船看成一種船,然後進行01揹包判斷有多少種裝滿的方案。

AC程式碼

#include <iostream>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const ll mod = 1e9 + 7;
ll dp[10005];
int val[10005], cnt[10005];
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		memset(dp, 0, sizeof dp);
		dp[0] = 1;
		int n, m, q;
		scanf("%d%d", &n, &m);
		for (int i = 0; i < n; i++)
		{
			scanf("%d%d", &val[i], &cnt[i]);
			for (int j = 0; j < cnt[i]; j++)
			{
				ll temp = val[i] * (1 << j);
				for (int k = 10004; k >= temp; k--)
					dp[k] = (dp[k] + dp[k - temp]) % mod;
			}
		}
		for (int i = 0; i < m; i++)
		{
			scanf("%d", &q);
			printf("%lld\n", dp[q]);
		}
	}
}