列表

详情


NC205306. 动物森友会

描述

Compute 最近开始玩动物森友会了。
这个游戏的时间与现实时间是同步的(一周有 7 天),而一些特定事件只会在一周的某些天解锁。
我们假设有 n 个不同的事件,而每个事件都会给予不同的材料,并且每个事件只会在一周中的特定几天开放,在开放的时间内可以完成多次。但由于 Compute 要参加训练,他每天并没有多少时间玩游戏,所以他每天最多只能完成 e 次事件。
现在 Compute 想做出一件非常稀有的道具——高达,并且他计算出了他收集齐所有材料需要完成每一种事件的次数。
假设现在 Compute 从周一开始玩这个游戏,他最少需要经过几天(包括不玩游戏的日子)才能造出高达?

输入描述

第一行包含 2 个整数 n, e (, ),中间以空格分隔,分别表示不同事件的数量和 Compute 一天能完成的事件次数。
接下来 n 行,每行包含 个整数 c_i, m_i, (, , , ),中间以空格分隔,分别表示事件 i 需要完成的次数、事件开放的天数和事件 i 在一周中的哪些时间会开放。

输出描述

在一行输出一个整数,表示 Compute 造出高达的最少天数。

示例1

输入:

5 2
2 4 1 3 5 7
2 3 2 4 6
2 2 1 2
2 2 3 4
2 2 5 6

输出:

5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 17ms, 内存消耗: 608K, 提交时间: 2020-05-01 09:02:33

#include<bits/stdc++.h>

using namespace std;
using ll = long long;
using pii = pair<int, int>;
using db = double;
using vi = vector<int>;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define debug(x) cout << #x <<"\t" << x <<endl
const int inf = 0x3f3f3f3f;
const db eps = 1e-8;
const int mod = 1e9+7;
ll qpow(ll a, ll b){
	ll ret = 1;
	while(b){
		if(b&1)ret = ret*a%mod;
		a = a*a%mod;
		b>>=1;
	}
	return ret;
}
int n, e;
int sta[1010];
int c[1010], num[10];
bool check(int x){
	memset(num, 0, sizeof(num));
	for(int i=1; i<=7; ++i) num[i] = x/7;
	for(int i=1; i<=x%7; ++i) num[i]++;
	for(int msk = 0; msk<(1<<7); msk++){
		ll R=0;
		for(int i=1; i<=7; ++i) if(msk&(1<<(i-1)))R += 1ll*num[i]*e;
		ll L = 0;
		for(int i=1; i<=n; ++i) if((sta[i]&msk)==sta[i]) L += c[i];
		if(L>R)return 0;
	}
	return 1;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> e;
	for(int i=1; i<=n; ++i){
		cin >> c[i];
		int m; cin >> m;
		int msk = 0;
		while(m--){
			int x;cin>> x;
			msk |= (1<<(x-1));
		}
		sta[i] = msk;
	}
	int l = 1, r = 700000000;
	while(l<=r){
		int m = l+r>>1;
		if(check(m)) r = m-1;
		else l = m+1;
	//	debug(m);
	}
	cout <<  l <<"\n";
}



C++(clang++ 11.0.1) 解法, 执行用时: 4ms, 内存消耗: 472K, 提交时间: 2023-03-15 08:27:19

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int i,j,k,x,n,e,ans=0,R[135]={0};
	scanf("%d%d",&n,&e);
	while(n--)
	{
		bool V[7]={0};
		scanf("%d%d",&x,&k);
		for(i=0;i<k;i++)scanf("%d",&j),V[j-1]=1;
		for(i=1;i<128;i++)
		{
			for(j=0;j<7;j++)if(V[j]&&!((1<<j)&i))break;
			if(j==7)R[i]+=x;
		}
	}
	for(i=1;i<(1<<7);i++)
	{
		if(!R[i])continue;
		n=__builtin_popcount(i),k=R[i]/e+(R[i]%e?1:0);
		for(j=0;j<7;j++)
		{
			if(!((1<<j)&i))continue;
			if((--k)%n==0)break;
		}
		ans=max(ans,k/n*7+j+1);
	}
	printf("%d\n",ans);
    return 0;
}

上一题