T736185 衣服 (clothes) 赛后题解

题目传送门

思路

发现室温最底值为 \(-40\),离目标温度只差 \(63\)
对于任意的一组室温,可以构造衣服保暖效果为 \(\{1,2,4,8,16,32\}\),共 \(6\) 件衣服,说明答案最大为 \(6\)

显然,买两件相同的衣服不如买两件不同的衣服,如买 \(\{a,a\}\) 不如 \(\{a,2a\}\)

做法

考虑状态压缩搜索。
定义 now 为当前买了哪些档次的衣服,每次转移将所有能买的全部或上,即 now|=(now<<i),其中 i 为要买的衣服的档次。

可以再加一些剪枝。

时间复杂度玄学,跑满大概 \(8\times10^7\),可以通过。

后记:场上脑抽,没想到用 long long 存状态,于是用 bitset 做的,常数大 4 倍。(不过也过了)

代码
#include<bits/stdc++.h>
using namespace std;
long long goal;
int ans;
void dfs(int id, int maxn, int mn, int n, int las, int cnt, long long now)
{
	if(cnt >= ans) return;
	if(id > maxn)
	{
		if((now & goal) != goal) return;
		ans = min(ans, cnt);
		return;
	}
	long long nnow;
	for(int i = (las ? las + 1 : las); i <= mn; i ++)
	{
		nnow = now;
		nnow |= (nnow << i);
		dfs(id + 1, maxn, mn, n, i, cnt + (i > 0), nnow);
	}
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	freopen("clothes.in", "r", stdin);
	freopen("clothes.out", "w", stdout);
	int _;
	cin >> _;
	while(_ --)
	{
		goal = 0;
		int n;
		cin >> n;
		int val, maxn = 0;
		for(int i = 1; i <= n; i ++)
		{
			cin >> val;
			goal |= (1ll << (23 - val));
			maxn = max(maxn, 23 - val);
		}
		ans = 6;
		dfs(1, min(5, n), maxn, n, 0, 0, 1);
		cout << ans << endl;
	}
	return 0;
}

posted @ 2026-02-25 17:45  yuzihang  阅读(33)  评论(0)    收藏  举报