首页 > 其他 > 详细

nowcoder 2020/6/20 J-小梁的背包

时间:2020-06-20 19:12:24      阅读:77      评论:0      收藏:0      [点我收藏+]

小梁来到了伽勒尔地区并参加了联盟赛热身赛,比赛小岛上有n个精灵散落在岛上各处,她有一个大小为s的背包,每个精灵的战斗值为vi,体积为wi。
请问在她临走之前背包内宝可梦的战斗力总和最多为多少,并输出其战斗值总和sum以及背包内的精灵数量ans。

技术分享图片

示例1
输入

1
5 5
1 3
2 5
1 2
4 2
6 1

输出

10 3

背包问题,问了同学他说好像是多重背包?
赛后搜得:背包问题详解

这题恶心的地方是用dp求出最大的价值后还要让你计数,问放进去了多少个精灵球,卡了非常久。

dp部分:
我原本将这个计数的设为是cnt[i][j]=cnt[i-1][j];
然后if判断是否放入,放入则cnt[i][j]++。这样是错误的,因为价值更新的话应该是前面那个容量的背包的次数再加一,而不是简单的++。
应该改为

cnt[i][j]=cnt[i-1][j];	

//.....

cnt[i][j]=cnt[i-1][j-g[i].w]+1;

正解:

	for(int i=1;i<=n;i++){
		for(int j=0;j<=s;j++){
			dp[i][j]=dp[i-1][j];
			cnt[i][j]=cnt[i-1][j];	
			if(j>=g[i].w){
				if(dp[i-1][j-g[i].w]+g[i].v>dp[i-1][j]){
					dp[i][j]=dp[i-1][j-g[i].w]+g[i].v;
					cnt[i][j]=cnt[i-1][j-g[i].w]+1;
				}				
			}
		}
	}

完整代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;

struct gg{
	int v,w;
}g[N];
int dp[N][N];
int cnt[N][N];
void solve()
{
	int n,s;
	cin>>n>>s;
	for(int i=1;i<=n;i++)cin>>g[i].w>>g[i].v;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=s;j++){
			dp[i][j]=dp[i-1][j];
			cnt[i][j]=cnt[i-1][j];	
			if(j>=g[i].w){
				if(dp[i-1][j-g[i].w]+g[i].v>dp[i-1][j]){
					dp[i][j]=dp[i-1][j-g[i].w]+g[i].v;
					cnt[i][j]=cnt[i-1][j-g[i].w]+1;
				}				
			}
		}
	}
	cout<<dp[n][s]<<" "<<cnt[n][s]<<endl;
}

int main()
{
	ios::sync_with_stdio(false);	
	int t;
	cin>>t;
	while(t--)solve();
	return 0;
}

dp仍然是我比较不熟练的部分,需要多做相关的题目。

nowcoder 2020/6/20 J-小梁的背包

原文:https://www.cnblogs.com/LiangYC1021/p/13169974.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!