动态规划专题:找啊找啊找GF

题目描述:

"找啊找啊找GF,找到一个好GF,吃顿饭啊拉拉手,你是我的好GF.再见."
"诶,别再见啊..."
七夕...七夕...七夕这个日子,对于sqybi这种单身的菜鸟来说是多么的痛苦...虽然他听着这首叫做"找啊找啊找GF"的歌,他还是很痛苦.为了避免这种痛苦,sqybi决定要给自己找点事情干.他去找到了七夕模拟赛的负责人zmc MM,让她给自己一个出题的任务.经过几天的死缠烂打,zmc MM终于同意了.
但是,拿到这个任务的sqybi发现,原来出题比单身更让人感到无聊-_-....所以,他决定了,要在出题的同时去办另一件能够使自己不无聊的事情--给自己找GF.
sqybi现在看中了n个MM,我们不妨把她们编号1到n.请MM吃饭是要花钱的,我们假设请i号MM吃饭要花rmb[i]块大洋.而希望骗MM当自己GF是要费人品的,我们假设请第i号MM吃饭试图让她当自己GF的行为(不妨称作泡该MM)要耗费rp[i]的人品.而对于每一个MM来说,sqybi都有一个对应的搞定她的时间,对于第i个MM来说叫做time[i]. sqybi保证自己有足够的魅力用time[i]的时间搞定第i个MM^_^.
sqybi希望搞到尽量多的MM当自己的GF,这点是毋庸置疑的.但他不希望为此花费太多的时间(毕竟七夕赛的题目还没出),所以他希望在保证搞到MM数量最多的情况下花费的总时间最少.
sqybi现在有m块大洋,他也通过一段时间的努力攒到了r的人品(这次为模拟赛出题也攒rp哦~~).他凭借这些大洋和人品可以泡到一些MM.他想知道,自己泡到最多的MM花费的最少时间是多少.
注意sqybi在一个时刻只能去泡一个MM--如果同时泡两个或以上的MM的话,她们会打起来的...

大致思路:

这是一个0/1揹包的变种,条件是rp和rmb二维的,然后对于每一个状态需要记录两个条件:搞定的MM数目,和所需要花的时间;

由于需要保证MM的数量,

于是就有了状态转移方程,从一个状态转移过来的新状态下,如果MM数小于原状态+1,就直接更新时间,如果MM数等于原状态+1就将时间更新成小的,否则就不更新。

在计算最后的答案时,先找到规定rmb和rp范围内搞定的MM最大值,然后记录这个最大值状态下的时间最小值。

代码:

#include <iostream>
#include <cstring>

using namespace std;

struct girl {
	int num,time;
};

int n,m,r;
girl st[201][201];
bool c[201][201];

int main() {
	for (int i = 0; i<201; i++) {
		for (int j = 0; j<201; j++) {
			st[i][j].num = 0;
			st[i][j].time = 0x3f3f3f3f;
		}
	}
	memset(c,0,sizeof(c));
	c[0][0] = true;
	st[0][0].time = 0;
	cin>>n;
	while (n--) {
		int rmb,rp,time;
		cin>>rmb>>rp>>time;
		for (int i = 100; i>=0; i--) {
			for (int j = 100; j>=0; j--) {
				if (c[i][j]) {
					c[i+rmb][j+rp] = true;
					if (st[i][j].num+1>st[i+rmb][j+rp].num) {
						st[i+rmb][j+rp].num = st[i][j].num+1;
						st[i+rmb][j+rp].time = st[i][j].time+time;
					}
					else if (st[i][j].num+1==st[i+rmb][j+rp].num) {
						st[i+rmb][j+rp].time = min(st[i+rmb][j+rp].time,st[i][j].time+time);
					}
				}
			}
		}
	}
	cin>>m>>r;
	int girls = 0;
	for (int i = 1; i<=m; i++) {
		for (int j = 1; j<=r; j++) {
			girls = max(girls,st[i][j].num);
		}
	}
	if (!girls) {
		cout<<"0"<<endl;
	}
	else {
		int ans = 0x3f3f3f3f;
		for (int i = 1; i<=m; i++) {
			for (int j = 1; j<=r; j++) {
				if (st[i][j].num == girls) ans = min(ans,st[i][j].time);
			}
		}
		cout<<ans<<endl;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章