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;
}
hello, I'm yuzihang, if you need to copy this, please quote this url: https://www.cnblogs.com/yuzihang/p/19638206

浙公网安备 33010602011771号