BZOJ5018: [Snoi2017]英雄联盟

数据范围有点大?超级不可做?

其实算算 n 的最大值,发现那 m 根本就是虚的,∑i=1nk[i] * c[i] <= 243552

这就可以直接上背包了

最裸最暴力的那种

可以选择滚动数组,并不能减掉一维,因为在重复枚举 j 的时候除第一次枚举之外都会用到当前这一层的状态


代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cstdio>
using namespace std;
 
typedef long long ll;
const int MAXN = 123;
 
int n, totm;
int sum[MAXN], cst[MAXN], ans = 2147483644;
ll m;
ll f[MAXN][243552];
 
int main() {
    scanf("%d%lld", &n, &m);
    for(int i = 1; i <= n; ++i) scanf("%d", &sum[i]);
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &cst[i]);
        totm += cst[i] * sum[i];
    }
    f[0][0] = 1ll;
    for(int ii = 1; ii <= n; ++ii) {
    	int i = (ii & 1);
        for(int k = 0; k <= totm; ++k) {
        	f[i][k] = f[i ^ 1][k];
            for(int j = 0; j <= sum[ii] && k >= j * cst[ii]; ++j) {
                f[i][k] = min(m, max(f[i][k], f[i ^ 1][k - j * cst[ii]] * (ll)j));
                if(f[i][k] == m) ans = min(ans, k);
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/xcysblog/p/9624253.html