1 条题解

  • 1
    @ 2023-3-8 21:59:46

    这道题其实挺简单的

    这道题一看就是dp题,但是标签里还打了模拟,搜索,贪心? 我的是完全背包在加上一个数组uu来记录已经使用的个数,这道题不能算是一个多重背包,因为多重背包是每个物品都有数量限制,而这道题只有总数量限制,我们在正常递推的过程中加上总数量和能否成功组合的判断就行

    一,划分阶段

    以总面额和面额种类划分

    二,确定状态变量

    dp[i]dp[i]表示有多少种方法可以组合出面值ii,但是如果光有dpdp数组可不行,因为邮票的总数有限制,所以我们增加一个数组uu表示used,也就是组出面值ii所需要的最小邮票数

    三,状态转移方程

    dpdp数组的状转特别简单,dp[i]dp[i]可以通过dp[ia[j]]dp[i-a[j]]求得,其中a[j]a[j]表示第jj种邮票的面额,状转为dp[i]+=dp[i-a[j]]u[i]u[i]的状态可以在u[i]u[i]u[ia[j]]+1u[i-a[j]]+1中取最小值转移,那我们需要通过memset来初始化uu数组,memset是通过字节赋值,如果我们在第二个参数填0x3f,那么将会赋一个极大值,0x7f是最大,讲完初始化我们的状转是u[i]=min(u[i],u[i-a[j]]+1)

    四,设置边界

    dp[0]=1 u[0]=0

    五,ACCODE

    #include<bits/stdc++.h>
    using namespace std;
    int k,n,a[51],dp[10000001],u[10000001];
    int main()
    {
    	cin>>k>>n;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	dp[0]=1;
    	memset(u,0x3f,sizeof(u));//为了比最小值,要赋一个极大值
    	u[0]=0;
    	int i;
    	for(i=1;;i++)//第二个参数不填就会一直只需,所以要借助break
    	{
    		if(u[i-1]>k)//如果上一个的使用数量超过限制,就算失败
    		{
    			i-=2;//上一个不行,最终结果就-2
    			break;
    		}
    		for(int j=1;j<=n;j++)
    		{
    			if(a[j]<=i)//不加这个判断会越界
    			{
    				dp[i]=dp[i-a[j]];
    				u[i]=min(u[i],u[i-a[j]]+1);//状态转移
    			}
    		}
    		if(!dp[i])//没有求出i的组合,答案算上一个
    		{
    			i--;
    			break;
    		}
    	}
    	cout<<i;//i也相当于最多连续的数量
    }
    

    等一等,先别划走,还可以优化,首先观察题目,可以发现状态数组只需要开2000001个,不需要开10000001个, 然后dp其实只需要1和0两种状态就够,开boolbool 接着对uu的判断也不需要下一轮,直接和对dpdp的判断合在一起

    LATEST ACCODE

    #include<bits/stdc++.h>
    using namespace std;
    int k,n,a[51],u[2000001];
    bool dp[2000001];//降低空间复杂度
    int main()
    {
    	cin>>k>>n;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	dp[0]=1;
    	memset(u,0x3f,sizeof(u));
    	u[0]=0;
    	int i;
    	for(i=1;;i++)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			if(a[j]<=i)
    			{
    				dp[i]+=dp[i-a[j]];
    				u[i]=min(u[i],u[i-a[j]]+1);
    			}
    		}
    		if(!dp[i]||u[i]>k)//将两个判断合并
    		{
    			i--;
    			break;
    		}
    	}
    	cout<<i;
    }
    
    • 1

    信息

    ID
    589
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    54
    已通过
    14
    上传者