华为oj 购物单


这两天断断续续敲完这个(放假的时候比较懒),一次成功有点小激动(●'◡'●)  不过貌似从第一次打开开始计时。。。。。

这道题目很像01背包,我将附件与它们的主件绑定(就是link起来)然后套用动态规划

ok,解决

#include<iostream>
#include<vector>
using namespace std;

class node {//代表主件的类
public:
	int value;
	int p;//重要度
	int n;//附件个数
	int q;//附件指向的主件编号
	node *link;
	node():value(0),p(0),n(0),q(0),link(nullptr){}
};

int judge(vector<node*>& vc,int N,int m);
int max(int, int);

int main()
{
	int N, m;
	vector<node*> vc;
	cin >> N >> m;
	for (int i = 0;i < m;i++) {
		int vi, pi, qi;
		cin >> vi >> pi >> qi;
		node *np = new node();
		np->value = vi;
		np->p = pi;
		np->q = qi;
		vc.push_back(np);
	}
	for (vector<node*>::iterator i = vc.begin();i != vc.end();i++) {
		int tmp = (*i)->q;
		if (tmp > 0) {
			if(vc[tmp-1]->link==nullptr)
				vc[tmp - 1]->link = *i;
			else
				vc[tmp - 1]->link->link = *i;
			vc[tmp - 1]->n++;
		}

	}
	for (vector<node*>::iterator i = vc.begin();i != vc.end();) {
		int tmp = (*i)->q;
		if (tmp > 0) {
			i=vc.erase(i);
		}
		else {
			++i;
		}

	}
	cout<<judge(vc, N, m)<<endl;
    return 0;
}
int judge(vector<node*>& vc, int N, int m) {
	//任务 返回经过计算的结果
	//建立一个int[3200][60]数组 因为N为10的倍数
	int tb[3200][60] = {0};
	vector<node*>::iterator ib = vc.begin();
	for (int i = 1;i <= N / 10;i++) {
		if ((*ib)->n == 0) {
			if ((*ib)->value <= i*10) {
				tb[i][1] = ((*ib)->value*(*ib)->p);
			}
		}
		if ((*ib)->n == 1) {
			if (((*ib)->value+(*ib)->link->value) <= i*10) {
				tb[i][1] = ((*ib)->value*(*ib)->p)+ ((*ib)->link->value*(*ib)->link->p);
			}
			else {
				tb[i][1] = ((*ib)->value*(*ib)->p);
			}
		}
		if ((*ib)->n == 2) {
			if (((*ib)->value + (*ib)->link->value+ (*ib)->link->link->value) <= i*10) {
				tb[i][1] = ((*ib)->value*(*ib)->p) + ((*ib)->link->value*(*ib)->link->p)+ ((*ib)->link->link->value*(*ib)->link->link->p);
			}
			else if (((*ib)->value + (*ib)->link->value) <= i*10) {
				tb[i][1] = ((*ib)->value*(*ib)->p) + ((*ib)->link->value*(*ib)->link->p);
			}
			else {
				tb[i][1] = ((*ib)->value*(*ib)->p);
			}
		}
	}
	++ib;//使迭代器指向下一个元素
	int j=1;
	for (;ib != vc.end();ib++,j++) {
		for (int i = 1;i <= N / 10;i++) {

			if ((*ib)->n == 0) {//没有附件
				int tmp1 = (*ib)->value;
				int tmp1_ = (*ib)->p;
				if (tmp1 > i * 10) {
					tb[i][j] = tb[i][j - 1];
				}
				else {
					tb[i][j] = max(tb[i][j - 1], tb[i - tmp1 / 10][j - 1] + tmp1*tmp1_);
				}
			}

			if ((*ib)->n == 1) {//有一个附件
				int tmp1 = (*ib)->value;
				int tmp1_ = (*ib)->p;
				int tmp2 = (*ib)->link->value;
				int tmp2_ = (*ib)->link->p;

				if (tmp1 > i * 10) {
					tb[i][j] = tb[i][j - 1];
				}
				else if ((tmp1 + tmp2) > i * 10) {
					tb[i][j] = max(tb[i][j - 1], tb[i - tmp1 / 10][j - 1] + tmp1*tmp1_);
				}
				else {
					int m1= max(tb[i][j - 1], tb[i - tmp1 / 10][j - 1] + tmp1*tmp1_);
					tb[i][j] = max(m1, tb[i - (tmp1+tmp2) / 10][j - 1] + tmp1*tmp1_+tmp2*tmp2_);
				}
			}

			if ((*ib)->n == 1) {//有两个附件
				int tmp1 = (*ib)->value;
				int tmp1_ = (*ib)->p;
				int tmp2 = (*ib)->link->value;
				int tmp2_ = (*ib)->link->p;
				int tmp3= (*ib)->link->link->value;
				int tmp3_ = (*ib)->link->link->p;
				if (tmp1 > i * 10) {
					tb[i][j] = tb[i][j - 1];
				}
				else if ((tmp1 + tmp2) > i * 10) {
					tb[i][j] = max(tb[i][j - 1], tb[i - tmp1 / 10][j - 1] + tmp1*tmp1_);
				}
				else if((tmp1+tmp2+tmp3)>i*10){
					int m1 = max(tb[i][j - 1], tb[i - tmp1 / 10][j - 1] + tmp1*tmp1_);
					tb[i][j] = max(m1, tb[i - (tmp1 + tmp2) / 10][j - 1] + tmp1*tmp1_ + tmp2*tmp2_);
				}
				else {
					int m1 = max(tb[i][j - 1], tb[i - tmp1 / 10][j - 1] + tmp1*tmp1_);
					int m2= max(m1, tb[i - (tmp1 + tmp2) / 10][j - 1] + tmp1*tmp1_ + tmp2*tmp2_);
					tb[i][j] = max(m2, tb[i - (tmp1 + tmp2 + tmp3) / 10][j - 1] + tmp1*tmp1_ + tmp2*tmp2_ + tmp3*tmp3_);
				}
			}



		}
	}
	return tb[N/10][j-1];

}

int max(int a, int b) {
	if (a > b)
		return a;
	else
		return b;
}



原文地址:https://www.cnblogs.com/odin-luyu/p/5371772.html