专栏文章

题解:AT_abc404_d [ABC404D] Goin' to the Zoo

AT_abc404_d题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipdsdhh
此快照首次捕获于
2025/12/03 10:21
3 个月前
此快照最后确认于
2025/12/03 10:21
3 个月前
查看原文

题意

AtCoder 国有 nn 个动物园,第 ii 个动物园门票为 CiC_i 元,一个人要去动物园看动物,他喜欢 MM 种动物,第 ii 种动物在 KiK_i 个动物园里有,这 KiK_i 个动物园分别是 Ai,1,, Ai,KiA_{i,1},\dots,\ A_{i,K_i},他要求每种他喜欢的动物都要看两遍,问他最少要花多少钱。

思路

因为每个动物只看两遍,所以一个动物园最多去两次,我们就可以用三进制枚举每个动物园去几次就行了。时间复杂度 O(3n)O(3^n)

代码

CPP
#include <bits/stdc++.h>
using namespace std;
long long n,m,a[1001][1001],b[1001],c[1001],d[1001],e[1001],ans=1e18;
void dfs(long long i,long long x){
	if(x>=ans){
		return;
	}
	if(i==n+1){
		for(long long j=1;j<=m;j++){
			for(long long k=1;k<=c[j];k++){
				e[j]+=d[a[j][k]];
			}
		}
		bool ok=1;
		for(long long j=1;j<=m;j++){
			if(e[j]<2){
				ok=0;
			}
			e[j]=0;
		}
		if(ok){
			ans=x;
		}
		return;
	}
	d[i]=0;
	dfs(i+1,x);
	d[i]=1;
	dfs(i+1,x+b[i]);
	d[i]=2;
	dfs(i+1,x+b[i]*2);
}
int main(){
	scanf("%lld%lld",&n,&m);
	for(long long i=1;i<=n;i++){
		scanf("%lld",&b[i]);
		b[i+n]=b[i];
	}
	for(long long i=1;i<=m;i++){
		scanf("%lld",&c[i]);
		c[i+n]=c[i];
		for(long long j=1;j<=c[i];j++){
			scanf("%lld",&a[i][j]);
			a[i+n][j]=a[i][j];
		}
	}
	dfs(1,0);
	printf("%lld",ans);
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...