题解

三途川的摆渡人

https://ac.nowcoder.com/acm/contest/77231/F

这场被打爆了,写一下F的题解吧

  • 大家好像都用的状压或者背包去做的,我贡献一个比较简单的做法。
  • 表示当前i状态最少需要多少个数位与形成。
  • 不难发现,重复的点对于答案的贡献为0,我们可以排序去重后线性dp一遍就行(这么做的话值域范围完全可以放到1000,这个题的值域范围比较小,也可以不去重排序直接做一遍就行)
#include <bits/stdc++.h>

#define x first
#define y second
#define pb push_back

using namespace std;

const int N = 2e5 + 10;
const int P = 1e9 + 7, INF = 0x3f3f3f3f;

typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef long long LL;

void solve() {
    int n;
    cin >> n;
    vector<int> a(n);
    vector<int> f(201, INF); //选择尽可能少的位与为0

    for(int i = 0; i < n; i ++ ) 
        cin >> a[i];
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end()) - a.begin();

    for(int i = 0; i < a.size(); i ++ ) {
        f[a[i]] = 1;
        for(int j = 0; j <= 200; j ++ )
            f[j & a[i]] = min(f[j & a[i]], f[j] + 1);
    }
    if(f[0] == INF) cout << "-1\n";
    else cout << n - f[0] << '\n';

}

int main() {
    //cout << log(200) / log(2) << '\n';
    int T = 1;
    cin >> T;
    while(T -- ) {
        solve();
    }
    return 0;
}
全部评论
for(int j = 0; j <= 200; j ++ )j取这么多为什么不会对结果产生影响啊
点赞 回复 分享
发布于 2024-03-25 17:50 河北
天才
点赞 回复 分享
发布于 2024-03-19 20:05 河南

相关推荐

我要娶个什么名:学长你电脑闹鬼了
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
12
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务