题意:
有m层,每层的boss有n个特殊部位,要击破某个部位需要吃多个cake,当然也可以不打。每层在打BOSS之前还可以捡到一些cake。求能击破的特殊部位最大数。
题解:
将特殊部位所需cake从小到大排序,对于当前的部位,设其在第i层,查询1~i剩余cake数是否足够,足够的话从i~1选cake来击破它。
//Time:500ms
//Memory:7992KB
//Length:1481B
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
#define MAXN 1000010
#define MAXT 1300
#define INF 1000000007
map<int,int> ma;
pair<int,int> pa[MAXN];
int main()
{
//freopen("/home/moor/Code/input","r",stdin);
int ncase,top;
scanf("%d",&ncase);
while (ncase--)
{
top=0;
int n,m;
ma.clear();
scanf("%d",&m);
for(int i=1;i<=m;++i)
{
scanf("%d",&n);
for(int j=0;j<n;++j) scanf("%d",&pa[top].first),pa[top++].second=i;
}
for(int i=1;i<=m;++i)
{
int tmp;
scanf("%d",&tmp);
if(tmp==0) continue;
ma[-i]=tmp;
}
sort(pa,pa+top);
int ans=0;
for(int i=0;i<top;++i)
{
int tmp=pa[i].first,tt;
int sum=0;
map<int,int> ::iterator ite=ma.lower_bound(-pa[i].second);
for(;ite!=ma.end()&&sum<tmp;++ite)
sum+=ite->second;
if(sum<tmp) continue;
++ans;
ite=ma.lower_bound(-pa[i].second);
for(;ite!=ma.end()&&tmp;)
{
tt=min(ite->second,tmp);
tmp-=tt,ite->second-=tt;
map<int,int> ::iterator ite2=ite;
++ite;
if(ite2->second==0) ma.erase(ite2->first);
}
}
printf("%d\n",ans);
}
return 0;
}