• 「SNOI2017」英雄联盟


    题目描述

    正在上大学的小皮球热爱英雄联盟这款游戏,而且打的很菜,被网友们戏称为「小学生」。
    现在,小皮球终于受不了网友们的嘲讽,决定变强了,他变强的方法就是:买皮肤!
    小皮球只会玩 NNN 个英雄,因此,他也只准备给这 NNN 个英雄买皮肤,并且决定,以后只玩有皮肤的英雄。
    这 NNN 个英雄中,第 iii 个英雄有 KiK_iKi​ 款皮肤,价格是每款 CiC_iCi​ Q币(同一个英雄的皮肤价格相同)。
    为了让自己看起来高大上一些,小皮球决定给同学们展示一下自己的皮肤,展示的思路是这样的:对于有皮肤的每一个英雄,随便选一个皮肤给同学看。
    比如,小皮球共有 5 个英雄,这 5 个英雄分别有 0,0,3,2,4&0,0,3,2,4&0,0,3,2,4 款皮肤,那么,小皮球就有 3×2×4=24

    3×2×4=24 种展示的策略。
    现在,小皮球希望自己的展示策略能够至少达到 MMM 种,请问,小皮球至少要花多少钱呢?

    共 10 组数据,第 iii 组数据满足:N≤max⁡(5,(log⁡2i)4)Nleqmax(5,(log_2i)^4)N≤max(5,(log2​i)4)
    100%100\%100% 的数据:M≤1017,1≤Ki≤10,1≤Ci≤199Mleq 10^{17},1leq K_ileq 10,1leq C_ileq 199M≤1017,1≤Ki​≤10,1≤Ci​≤199。保证有解。

    数据范围与原题相同,但测试数据由本站会员自制,并非原数据。
    时限已按照评测机速度调整,原题时限为 2000 ms。

    分析:因为c,k,n的范围很小,m的范围很大

    所以将钱数作为dp背包的限制条件,做一次多重背包

    #include<bits/stdc++.h>
    using namespace std;
    #define re register int
    #define ll long long
    inline void FRE()
    {
    	freopen(".in","r",stdin);
    	freopen(".out","w",stdout);
    }
    inline void FCL()
    {
    	fclose(stdin);
    	fclose(stdout);
    }
    priority_queue<int>mp;
    const int N=1e5+5;
    const int mod=1e9+7;
    const int inf=0x3fffffff;
    inline ll read()
    {
    	ll s=0,f=1;
    	char a=getchar();
    	while(a<'0'||a>'9')
    	{
    		if(a=='-')
    		f=-1;
    		a=getchar();
    	}
    	while(a>='0'&&a<='9')
    	{
    		s=(s<<3)+(s<<1)+a-48;
    		a=getchar();
    	}
    	return s*f;
    }
    inline void output(int x)
    {
    	int y=10,len=1;
    	while(y<=x)
    	{
    		y*=10;
    		len++;
    	}
    	while(len--)
    	{
    		y/=10;
    		putchar(x/y+48);
    		x%=y;
    	}
    }
    int n,tot;
    ll dp[N*20],m;
    int k[N],c[N];
    int main()
    {
    	//FRE();
    	n=read();
    	m=read();
    	for(re i=1;i<=n;i++)
    	{
    		k[i]=read();
    	}
    	for(re i=1;i<=n;i++)
    	{
    		c[i]=read();
    	}
    	for(re i=1;i<=n;i++)
    	tot+=k[i]*c[i];
    	dp[0]=1;
    	for(re i=1;i<=n;i++)
    	{
    		for(re j=tot;j>=0;j--)
    		{
    			for(re kk=1;kk<=k[i];kk++)
    			{
    				if(kk*c[i]>j)
    				break;
    				dp[j]=min(m,max(dp[j-kk*c[i]]*(ll)kk,dp[j]));
    			}
    		}
    	}
    	for(re i=0;i<=tot;i++)
    	{
    		if(dp[i]>=m)
    		{
    			cout<<i;
    			return 0;
    		}
    	}
    	//FCL();
    	return 0;
    }
    
  • 相关阅读:
    CentOS 配置自启动Redis
    WPF Popup全屏 弹出方法。解决只显示75%的问题。
    UpdatePanel控件的使用和局部刷新
    关于width与padding
    WPF 快捷方式
    深入浅出WPF——附加事件(Attached Event)
    控件属性使用代码动代绑定
    ICommand.CanExecuteChanged事件订阅对象的变化
    输入德文出现乱码现象的处理方法
    MVVM 模版里的控件怎样触发命令
  • 原文地址:https://www.cnblogs.com/qyh2003/p/9788034.html
Copyright © 2020-2023  润新知