• [BZOJ5018][Snoi2017]英雄联盟


    [BZOJ5018][Snoi2017]英雄联盟

    试题描述

    正在上大学的小皮球热爱英雄联盟这款游戏,而且打的很菜,被网友们戏称为「小学生」。现在,小皮球终于受不了网友们的嘲讽,决定变强了,他变强的方法就是:买皮肤!小皮球只会玩 (N) 个英雄,因此,他也只准备给这 (N) 个英雄买皮肤,并且决定,以后只玩有皮肤的英雄。这 (N) 个英雄中,第 (i) 个英雄有 (K_i) 款皮肤,价格是每款 (C_i) Q币(同一个英雄的皮肤价格相同)。为了让自己看起来高大上一些,小皮球决定给同学们展示一下自己的皮肤,展示的思路是这样的:对于有皮肤的每一个英雄,随便选一个皮肤给同学看。比如,小皮球共有 (5) 个英雄,这 (5) 个英雄分别有 (0,0,3,2,4) 款皮肤,那么,小皮球就有 (3 imes 2 imes 4=24) 种展示的策略。现在,小皮球希望自己的展示策略能够至少达到 (M) 种,请问,小皮球至少要花多少钱呢?

    输入

    第一行,两个整数 (N,M)

    第二行,(N) 个整数,表示每个英雄的皮肤数量 (K_i)

    第三行,(N) 个整数,表示每个英雄皮肤的价格 (C_i)

    (10) 组数据,第 (t) 组数据满足:(N leq max{5,log_2^4 t},M leq 10^{17},1 leq K_i leq 10,1 leq C_i leq 199)。保证有解

    输出

    一个整数,表示小皮球达到目标最少的花费。

    输入示例

    3 24
    4 4 4
    2 2 2
    

    输出示例

    18
    

    数据规模及约定

    见“输入

    题解

    我真是智商下线。。。这题都没想到 QAQ

    dp,因为 (M) 太大,考虑将价钱作为状态。于是有 (f_{i, j}) 表示考虑前 (i) 种皮肤,花了 (j) Q币,最大的方案数是多少。因为 (K_i leq 10),暴力转移即可。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    #define LL long long
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
    	if(Head == Tail) {
    		int l = fread(buffer, 1, BufferSize, stdin);
    		Tail = (Head = buffer) + l;
    	}
    	return *Head++;
    }
    LL read() {
    	LL x = 0, f = 1; char c = Getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
    	return x * f;
    }
    
    #define maxn 130
    #define maxc 258710
    
    int n, num[maxn], cost[maxn];
    LL M, f[maxn][maxc];
    
    int main() {
    	n = read(); M = read();
    	for(int i = 1; i <= n; i++) num[i] = read();
    	for(int i = 1; i <= n; i++) cost[i] = read();
    	
    	f[0][0] = 1; int mx = 0;
    	for(int i = 0; i < n; i++)
    		for(int j = 0; j <= mx; j++) if(f[i][j]) {
    			f[i+1][j] = max(f[i+1][j], f[i][j]);
    			for(int k = 2; k <= num[i+1]; k++)
    				f[i+1][j+k*cost[i+1]] = max(f[i+1][j+k*cost[i+1]], min(f[i][j] * k, M)),
    				mx = max(mx, j + k * cost[i+1]);
    		}
    	
    	for(int j = 0; j < maxc; j++) if(f[n][j] >= M) return printf("%d
    ", j), 0;
    	
    	return 0;
    }
    
  • 相关阅读:
    vue 定义全局函数和变量
    大学感受
    NOIP2018 游记
    NOI2018 游记
    THUSC 2018 游记
    APIO2018 游记
    SXOI2018游记
    poorpool 的 考场 NOI Linux 配置
    关于 poorpool
    NOIP2017 游记
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/7625465.html
Copyright © 2020-2023  润新知