3703: 昊昊的壮举之造福社会
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 12 Solved: 4
[ Submit][ Status][ Discuss]
Description
“A secret makes a woman woman.”——Vermouth
“图灵机”昊昊,修八尺有余,而形貌昳丽,∴闻名遐迩。(昊昊:你们天天黑我因为我长得太帅了“众女嫉余之蛾眉兮,谣诼谓余以善淫”,你们啊,naive!!)有关人士称,据内部可靠消息,昊昊受到了很多“知名人士”的青睐,曾经参观过昊昊的知名人士,比如轲老板&老(da)板(biao)娘(mei),董天师&潮,黄大大&土豆泥,还有各种黄学长等。
这天,昊昊默默在给自己带来无限仰慕buff的财神爷面前矗立,私语道:“我是不是该造福社会了呢?”Action speaks louder than words.于是昊昊决定迈出卖出自己的第一步。
“图灵机”要造福社会,必从素有“图灵机之乡”的大胡建开始。不是有句名言“图灵机要从娃娃抓起”?于是昊昊找来了胡建各路名校,如zpyz等,希望他们能够买下昊昊领导的n个图灵机们。由于图灵机也实行“n品中正制”,故每台图灵机的价格不一定相同,要想买下第i台图灵机需要花费W[i]CNY,而每所学校对这项造福社会的事业的重视程度也不同,第i所学校的可支配资金为mon[i]CNY。为了简化问题,不妨假设图灵机是不可以被拆卸的,因此一个图灵机只能造福一个学校,但是一个学校为了自己拥有更强大的实力可以拥有多个图灵机。
昊昊自然是希望能够有尽量多的图灵机实行光荣的造福社会的使命,但是他还要四处奔波推销自己,因此这个任务就交给你咯^_^(昊昊:替我挡着~)
Input
第一行一个N,接下来N行,每行一个MON[I]。
接下来一行是一个M,之后M行,每行一个数,W[I]。
Output
仅一个数,即最多能被买下的图灵机的个数。
Sample Input
20
10
4
8
7
10
9
Sample Output
HINT
数据规模与约定
样例说明:4台图灵机两所学校不能都买下,所以最多只能买下3台。其中一种方案:第一所学校买下前两台,第二所学校买下第三台。
对于100%的数据: 0<N<=10000,0<M<=400000,0<mon<=1500,0<wi<=128
Source
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 1E4 + 10;
const int maxm = maxn*40;
const int maxs = 1E6 + 10;
int n,m,tot,MaxMoney,Min,Max,c[maxn],
Last[130],mon[maxn],w[maxm],sum[maxm],top,
Now[maxs],Waste[maxs],I[maxs],Pos[maxs],Rest[maxs];
bool bo[maxn];
bool DFS(int pos,int waste)
{
if (waste > Max) return 0;
if (!pos) return 1;
int Now = Last[w[pos]];
for (int i = Now; i >= 1; i--) {
if (mon[i] < w[pos]) continue;
mon[i] -= w[pos];
int Add = 0;
if (mon[i] < Min) Add = mon[i];
Last[w[pos]] = i;
if (DFS(pos-1,waste + Add)) return 1;
mon[i] += w[pos];
}
Last[w[pos]] = Now;
return 0;
}
int getint()
{
char ch = getchar();
int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret*10 + ch - '0',ch = getchar();
return ret;
}
bool Judge(int now)
{
if (sum[now] > tot || w[now] > c[n]) return 0;
Max = tot - sum[now];
for (int i = 1; i <= n; i++) mon[i] = c[i];
for (int i = 1; i <= now; i++)
Last[w[i]] = n;
return DFS(now,0);
}
int main()
{
#ifdef DMC
//freopen("DMC.txt","r",stdin);
freopen("input5.in","r",stdin);
#endif
cin >> n;
for (int i = 1; i <= n; i++)
c[i] = getint(),tot += c[i];
cin >> m;
for (int i = 1; i <= m; i++)
w[i] = getint();
sort(w + 1,w + m + 1);
for (int i = 1; i <= n; i++)
if (c[i] < w[1])
tot -= c[i],bo[i] = 1;
int N = 0;
for (int i = 1; i <= n; i++)
if (!bo[i]) c[++N] = c[i];
sort(c + 1,c + N + 1); n = N;
for (int i = 1; i <= m; i++)
sum[i] = sum[i-1] + w[i];
int L = 0,R = m;
int posi = 1;
for (int i = 1; i <= m; i++) {
while (posi <= n && w[i] > c[posi])
++posi;
if (c[posi] >= w[i]) ++L,++posi;
}
while (R - L > 1) {
int mid = (L + R) >> 1;
if (Judge(mid)) L = mid;
else R = mid;
}
if (Judge(R)) cout << R;
else cout << L;
return 0;
}