完全背包变式
题目链接
翻译成人话的题目
某次比赛的最终结果需要晋级 n ∗ m − k n*m-k n∗m−k个人,该比赛有两种赛程组成,一种是比赛 c c c场晋级 n n n人,一种是比赛 d d d场晋级 1 1 1人。问满足晋级人数的最少比赛场次为多少
思路
两种背包,令 d p [ i ] dp[i] dp[i]为晋级 i i i人时最少需要的题目数量,问最小,初始化为大数,晋级 0 0 0人时需要 0 0 0题,所以 d p [ 0 ] = 0 dp[0]=0 dp[0]=0,完全背包板子打上去就行了,注意我们要找最小值,所以板子开的大一些,跑完后遍历找最小就行了
ACcode
#include<bits/stdc++.h>
using namespace std;
const int M = 1e5 + 9;
int dp[M], w[3], v[3];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int c, d, n, m, k;cin >> c >> d >> n >> m >> k;
//int v = n * m - k;
for (int i = 1;i < M;i++)dp[i] = 1e9;
dp[0] = 0;
w[1] = n;w[2] = 1;v[1] = c;v[2] = d;
for (int i = 1;i <= 2;i++) {
for (int j = w[i];j < M;j++) {
dp[j] = min(dp[j], dp[j - w[i]] +v[i]);
}
}
int ans = 1e9;
for (int i = n * m - k;i < M;i++)ans = min(ans, dp[i]);
cout << ans;
return 0;
}