栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

281. 硬币 - AcWing (多重背包,巧妙优化)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

281. 硬币 - AcWing (多重背包,巧妙优化)

281. 硬币 - AcWing 分析:
  • 容易想到暴力 O ( n m C i ) O(nmC_i) O(nmCi​),显然会 T T T
#include 
using namespace std;

const int N=105,M=1e5+5;
int a[N],c[N];
int f[M],g[M];
signed main()
{
	int n,m;
	while(cin>>n>>m && n)
	{
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<=n;i++) cin>>c[i];
		for(int i=1;i<=m;i++) f[i]=0;
		f[0]=1;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=c[i];j++)
            {
                for(int k=m;k>=a[i];k--) if(f[k-a[i]]) f[k]=1;
            }
		}
		int ans=0;
		for(int i=1;i<=m;i++) if(f[i]) ans++;
		cout< 
  • 考虑优化,多重背包的优化方式有两种,二进制和优先队列,但都被这题卡常了
  • 这题有个十分巧妙的优化:
    • f [ j ] f[j] f[j] 存在的条件: f [ j − a [ i ] ] f[j-a[i]] f[j−a[i]] o r or or f [ j − 2 ∗ a [ i ] ] f[j-2*a[i]] f[j−2∗a[i]] o r or or . . . ... ... o r or or f [ j − c [ i ] ∗ a [ i ] ] f[j-c[i]*a[i]] f[j−c[i]∗a[i]] 存在
    • 所以可以另开一个数组 g g g,记录上一个状态 f [ j − a [ i ] ] f[j-a[i]] f[j−a[i]] 用了多少个 a [ i ] a[i] a[i]
#include 
using namespace std;

const int N=105,M=1e5+5;
int a[N],c[N];
int f[M],g[M];
signed main()
{
	int n,m;
	while(cin>>n>>m && n)
	{
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<=n;i++) cin>>c[i];
		for(int i=1;i<=m;i++) f[i]=0;
		f[0]=1;
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<=m;j++) g[j]=0;
			for(int j=a[i];j<=m;j++) // 遍历从前往后
			{
				if(!f[j] && f[j-a[i]] && g[j-a[i]]
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/302319.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号