動態規劃專題:找啊找啊找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;
	}
}


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