2 条题解

  • 1
    @ 2022-11-24 22:32:11

    那么我们仍用01背包的思路去思考完全背包问题,01背包中的状态转移方程f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i])用的是从m-0的循环,为的是保证当前的状态从绝无可能放入当前物品的状态中继承得来(有点绕) 那么既然现在我们有无限件物品可以取,我们就可以把循环顺序变为从0到v,同时把f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i])改为f[i][j]=max(f[i-1][j],f[i][j-w[i]]+c[i]),这样我们当前的状态就是从可能已经放进n件第i件物品中转移过来的了 那么就解决了~

    #include<bits/stdc++.h>
    using namespace std;
    int w[5001],c[5001];
    int f[5001][5001],m,n;
    int main()
    {
    	scanf("%d%d",&m,&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d%d",&w[i],&c[i]);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		for(int v=1;v<=m;v++)
    		{
    			if(v<w[i]) f[i][v]=f[i-1][v];
    			else
    			{
    				f[i][v]=max(f[i-1][v],f[i][v-w[i]]+c[i]);
    			}
    		}
    	}
    	cout<<f[n][m];
    	return 0;
    }
    

    普通模板

    • 0
      @ 2022-11-24 22:30:46

      与01背包的优化同理

      #include<bits/stdc++.h>
      using namespace std;
      int w[2001],v[2001],f[2001],n,m;
      int main()
      {
      	cin>>m>>n;
      	for(int i=1;i<=n;i++)
      	{
      		cin>>w[i]>>v[i];
      	}
      	for(int i=1;i<=n;i++)
      	{
      		for(int j=w[i];j<=m;j++)
      		{
      			f[j]=max(f[j],f[j-w[i]]+v[i]);
      		}
      	}
      	cout<<f[m];
      	return 0;
      }
      

      一维优化

      • 1

      信息

      ID
      463
      时间
      1000ms
      内存
      256MiB
      难度
      4
      标签
      递交数
      54
      已通过
      26
      上传者