題目描述
正在上大學的小皮球熱愛英雄聯盟這款遊戲,而且打的很菜,被網友們戲稱為「小學生」。
現在,小皮球終於受不了網友們的嘲諷,決定變強了,他變強的方法就是:買面板!
小皮球只會玩 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;
}
}