「BSOJ1159」 揹包 - 貪心

題目描述

小C有一個神奇的揹包,每放進去一個物品,揹包的體積就會變大。
也就是說,每放進一個物品,揹包會被佔用一定的體積,但是緊接着揹包的總體積又會增大一定的值(注意是在放入物品後背包總體積才增大)。
小C發覺這個揹包十分好用,於是不由自主地想到了一個問題。
現在給出揹包初始容量V以及n個物品,每一個物品兩個值a, b,分別表示物品所佔體積和放入揹包後背包增大的體積。
小C想知道能否把所有物品裝進去?
因爲小C比較老實,這麼簡單的問題自然裝作不會做的樣子。
於是他來請教你。

輸入格式

輸入文件包含多組數據。
第一行一個數T表示數據組數。
對於每組數據,第一行兩個數n, h,接下來n行每行兩個數a, b表示物品所佔體積和放入揹包後背包增大的體積。

輸出格式

輸入輸出樣例

樣例輸入#1

1
3 5
3 1
4 8
8 3

樣例輸出#1

Yes

樣例輸入#2

3
7 9269
21366 1233
7178 23155
16679 23729
15062 28427
939 6782
24224 9306
22778 13606
5 22367
17444 5442
16452 30236
14893 24220
31511 13634
4380 29422
7 18700
25935 4589
24962 9571
26897 14982
20822 2380
21103 12648
32006 22912
23367 20674

樣例輸出#2

Yes
Yes
No

數據規模與範圍

對於1~4個測試點,T=10,1≤n≤9,1≤V≤100000,0≤a,b≤100000
對於5~8個測試點,T=20,1≤n≤1000,1≤V≤100000,0≤a,b≤100000
對於9~12個測試點,T=5,1≤n≤100000,1≤V≤1000,0≤a,b≤1000
對於13~16個測試點,T=500,1≤n≤1000,1≤V≤100000,0≤a,b≤100000
對於17~20個測試點,T=8,1≤n≤50000,1≤V≤100000,0≤a,b≤100000

分析

很明顯的貪心。一開始,我直接用每一個物品可增長的容量-物品體積,再累加,再加上揹包原來的容量,看它是否大於0,大於等於0就可以,小於0就不可以。但這樣最多隻能得80分。然後就重新看題,發現物品要放進去後才能增加容量。於是重新寫。從我們的認知方面將,對於放進去後都是增加容量的物品,肯定選擇體積小的先裝;對於都減少的,肯定選擇增加容量大的先裝;一增一減,讓增加的先裝,這樣能得到最優情況。詳細的證明就不再敘述了。最後一個個裝,看當前容量能否裝進去,如果不能,就是“No”。

代碼

80分代碼

#include <stdio.h>
#include <algorithm>
#include <deque>
#include <iostream>
using namespace std;
int cs;
long long n;
__int128 m;
__int128 read() {
	__int128 x=0;
	char ch=getchar();
	while (ch<'0'||ch>'9') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
int main() {
	scanf("%d",&cs);
	while (cs--) {
		scanf("%lld",&n);
		m=read();
		for (int i=1;i<=n;i++) {
			long long a,b;
			scanf("%lld%lld",&a,&b);
			m+=(b-a);
		}
		if (m>=0) puts("Yes");
		else puts("No");
	}
	return 0;
}

AC代碼

#include <stdio.h>
#include <algorithm>
#include <deque>
#include <iostream>
using namespace std;
int cs;
long long n,m;
bool flag;
struct node {
	int a,b;
	int cha;
}it[100005];
bool cmp(const node&a,const node&b) {
	if (a.cha>0&&b.cha>0) return a.a<b.a;
	if (a.cha<0&&b.cha<0) return a.b>b.b;
	return a.cha>b.cha;
}
int main() {
	scanf("%d",&cs);
	while (cs--) {
		scanf("%lld%lld",&n,&m);
		for (int i=1;i<=n;i++) {
			long long a,b;
			scanf("%lld%lld",&it[i].a,&it[i].b);
			it[i].cha=it[i].b-it[i].a;
		}
		sort(it+1,it+n+1,cmp);
		flag=1;
		for (int i=1;i<=n;i++) {
			if (m<it[i].a) {
				flag=0;
				break;
			}
			m+=it[i].cha;
		}
		if (flag) puts("Yes");
		else puts("No");
	}
	return 0;
}

 

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