题解 | #[NOIP2006]金明的预算方案#

[NOIP2006]金明的预算方案

https://ac.nowcoder.com/acm/problem/16671

我来提供一下我自己想出来的思路
我这个思路的优点是,当附件有很多很多个的时候,你不用去把每种情况都穷举出来
首先,我定义了两个二维数组,二维数组itemv和二维数组itemw,itemv和itemw当中的每一个数组的第一个元素是主件,其余的为附件
然后我的dp也是二维数组,第一个i代表前i个物体,第二个j代表的是价格的下标
然后关键来了,我强行把第一个主件给它加上去,然后剩余附件使用选择性的加上去,然后这样主件和他的附件过完一轮之后,与上一个主件附件进行比较大小,如果这次主件附件加上去比它大,那就保留,否则就回到上一次的进度。

#include<bits/stdc++.h>
using namespace std;
vector<vector<int>> itemv;//这个二维数组中的每一个数组的第一个元素是主件的价格,其余的为附件的价格
vector<vector<int>> itemw;//这个二维数组中的每一个数组的第一个元素是主件的重要程度,其余的为附件的重要程度
int dp[70][33000];//第一个i代表前i个物体,第二个j代表的是价格的下标
int id[10000];
void solve() {
	vector<int> temp(100, 0);
	itemv.push_back(temp);
	itemw.push_back(temp);
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= m;i++) {
		int v, p, q;
		cin >> v >> p >> q;
		if (q <= 0) {
			itemv.push_back(vector<int>(1, v));
			itemw.push_back(vector<int>(1, p));
			id[i] = id[i - 1] + 1;
		}
		else {
			itemv[id[q]].push_back(v);
			itemw[id[q]].push_back(p);
			id[i] = id[i - 1];//因为它输入的q是主件的行数,所以需要一个id数组来转换一下
		}
	}
	for (int i = 1;i < itemv.size();i++) {
		for (int j = 0;j < itemv[i].size();j++) {
				if (j == 0) {				//如果是主件
					for (int k = n;k >= itemv[i][0];k--) {
						dp[i][k] = dp[i - 1][k - itemv[i][j]] + itemv[i][j] * itemw[i][j];	//强行把当前这个主件给加上去
					}
				}
				else {					    //如果是附件
					for (int k = n;k >= itemv[i][0] + itemv[i][j];k--) {		//这里itemv[i][0] + itemv[i][j]就是主件和当前所对应的附件的价格相加后的值
						dp[i][k] = max(dp[i][k], dp[i][k - itemv[i][j]] + itemv[i][j] * itemw[i][j]);
					}
				}
		}
		for (int k = 0;k <= n;k++) {		
			dp[i][k] = max(dp[i][k], dp[i - 1][k]);		//在价格为k时,如果加完之后还没有上一轮加得多,那么就返回上一轮的进度
		}
	}
	cout << dp[itemv.size() - 1][n] << endl;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	solve();
	return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 16:48
今天九点半到公司,我跟往常一样先扫了眼电脑,屁活儿没有。寻思着没事干,就去蹲了个厕所,回来摸出手机刷了会儿。结果老板刚好路过,拍了我一下说上班别玩手机,我吓得赶紧揣兜里。也就过了四十分钟吧,我的直属领导把我叫到小隔间,上来就给我一句:“你玩手机这事儿把老板惹毛了,说白了,你可以重新找工作了,等下&nbsp;HR&nbsp;会来跟你谈。”&nbsp;我当时脑子直接宕机,一句话都没憋出来。后面&nbsp;HR&nbsp;找我谈话,直属领导也在旁边。HR&nbsp;说我这毛病不是一次两次了,属于屡教不改,不光上班玩手机,还用公司电脑看论文、弄学校的事儿。我当时人都傻了,上班摸鱼是不对,可我都是闲得发慌的时候才摸啊!而且玩手机这事儿,从来没人跟我说过后果这么严重,更没人告诉我在公司学个习也算犯错!连一次口头提醒都没有,哪儿来的屡教不改啊?更让我膈应的是,昨天部门刚开了会,说四个实习生里留一个转正,让大家好好表现。结果今天我就因为玩手机被开了。但搞笑的是,开会前直属领导就把我叫去小会议室,明明白白告诉我:“转正这事儿你就别想了,你的学历达不到我们部门要求,当初招你进来也没打算给你这个机会。”合着我没入贵厂的眼是吧?可我都已经被排除在转正名单外了,摸个鱼至于直接把我开了吗?真的太离谱了!
rush$0522:转正名单没进,大概率本来就没打算留你
摸鱼被leader发现了...
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务