英雄聯盟(洛谷)

塵民發表於2020-10-06

題目描述
正在上大學的小皮球熱愛英雄聯盟這款遊戲,而且打的很菜,被網友們戲稱為「小學生」。

現在,小皮球終於受不了網友們的嘲諷,決定變強了,他變強的方法就是:買皮膚!

小皮球只會玩 N 個英雄,因此,他也只准備給這 N 個英雄買皮膚,並且決定,以後只玩有皮膚的英雄。

這 N 個英雄中,第 i 個英雄有 Ki 款皮膚,價格是每款 Ci Q 幣(同一個英雄的皮膚價格相同)。

為了讓自己看起來高大上一些,小皮球決定給同學們展示一下自己的皮膚,

展示的思路是這樣的:對於有皮膚的每一個英雄,隨便選一個皮膚給同學看。

比如,小皮球共有 5 個英雄,這 5 個英雄分別有 0, 0, 3, 2, 4 款皮膚,那麼,小皮球就有 3 × 2 × 4 = 24 種展示的策略。

現在,小皮球希望自己的展示策略能夠至少達到 M 種,請問,小皮球至少要花多少錢呢?

輸入格式
第一行,兩個整數 N, M。
第二行,N 個整數,表示每個英雄的皮膚數量 Ki
第三行,N 個整數,表示每個英雄皮膚的價格 Ci

輸出格式
一個整數,表示小皮球達到目標最少的花費。

輸入樣例
3 24
4 4 4
2 2 2

輸出樣例
18

樣例解釋
每一個英雄都只有 4 款皮膚,每款皮膚 2 Q幣,那麼每個英雄買 3 款皮膚, 3 × 3 × 3 ≥ 24,共花費 6×3 Q幣。

資料範圍
共 10 組資料,第 i 組資料滿足:N ≤ max(5, log42i)
對於 100% 的資料:M ≤ 1017,1 ≤ Ki ≤ 10, 1 ≤ Ci ≤ 199。保證有解。


題解
多重揹包(優化1.0):

#include <iostream>
using namespace std;

const int N = 1010, M = 500010;

long long n, m, QB;
long long c[N], s[N], f[M];

int main()
{
	cin >> n >> m;
	
	for (int i = 1; i <= n; i ++) cin >> s[i];
	
	for (int i = 1; i <= n; i ++)
	{
		cin >> c[i];
		QB += c[i] * s[i];
	}
	
	f[0] = 1;
	for (int i = 1; i <= n; i ++)
		for (int j = QB; j >= c[i]; j --)
			for (int k = 0; k * c[i] <= j && k <= s[i]; k ++)
				f[j] = max(f[j], f[j - k * c[i]] * k);
				
	for (int i = 1; i <= QB; i ++)
		if(f[i] >= m)
		{
			cout << i << endl;
			return 0;
		}			
}

相關文章