• Coco dfs 或者 状压dp。...


    C -- Coco

    Time Limit:1s Memory Limit:64MByte

    Submissions:148Solved:85

    DESCRIPTION

    Coco just learned a math operation call mod.Now,there is an integer aa and nn integers b1,,bnb1,…,bn. After selecting some numbers from b1,,bnb1,…,bn in any order, say c1,,crc1,…,cr, Coco want to make sure that amodc1modc2modmodcr=0amodc1modc2mod…modcr=0 (i.e., aa will become the remainder divided by cici each time, and at the end, Coco want aa to become 00). Please determine the minimum value of rr. If the goal cannot be achieved, print 1−1 instead.

    INPUT
    The first line contains one integer T(T5)T(T≤5), which represents the number of testcases. For each testcase, there are two lines: 1. The first line contains two integers nn and aa (1n20,1a1061≤n≤20,1≤a≤106). 2. The second line contains nn integers b1,,bnb1,…,bn (1in,1bi106∀1≤i≤n,1≤bi≤106).
    OUTPUT
    Print TT answers in TT lines.
    SAMPLE INPUT
    2 2 9 2 7 2 9 6 7
    SAMPLE OUTPUT
    2 -1

    先对数组排序,从大到小,因为mod大的数,不会对MOD小的数有影响,但是因为余数比MOD小的数更大,所以因子数只会更多。机会只会更多,就像样例一样,先MOD 7,再MOD 2.

    所以用dfs枚举每一个数,MOD和不MOD都选一次。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    #define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout
    #define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 1e6 + 20;
    int a[maxn];
    int n, ans;
    int val;
    void dfs(int selct, int re, int cur) {
        if (selct >= ans) return;
        if (re == 0) {
            ans = min(ans, selct);
            return;
        }
        if (cur > n) return;
        dfs(selct + 1, re % a[cur], cur + 1);
        dfs(selct, re, cur + 1);
    }
    void work() {
        scanf("%d%d", &n, &val);
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        sort(a + 1, a + 1 + n, greater<int>());
        ans = inf;
        dfs(0, val, 1);
        if (ans == inf) printf("-1
    ");
        else printf("%d
    ", ans);
    }
    
    int main() {
        freopen("data.txt","r",stdin);
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code

    状压:dp[state]表示现在MOD了那位数字,然后枚举的时候,也是优先MOD了大的数字,再转移去小的数字。不允许先MOD小的再转移去MOD大的,就是2--3这条路径是不行的,因为2--3就是先MOD2,再MOD1得到,但是可以先MOD1,再MOD2得到。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    #define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout
    #define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 2e6 + 20;
    int dp[maxn];
    int a[maxn];
    int get(int val) {
        int ans = 0;
        while (val) {
            val &= (val - 1);
            ans++;
        }
        return ans;
    }
    int cnt[maxn];
    void init() {
        int end = (1 << 20) - 1;
        for (int i = 0; i <= end; ++i) {
            cnt[i] = get(i);
        }
        return;
    }
    void work() {
        int ans = inf;
        int n, val;
        scanf("%d%d", &n, &val);
        for (int i = 0; i < n; ++i) {
            scanf("%d", &a[i]);
        }
        sort(a, a + n, greater<int>());
        memset(dp, 0x3f, sizeof dp);
        for (int i = 0; i < n; ++i) {
            dp[1 << i] = val % a[i];
            if (dp[1 << i] == 0) ans = 1;
        }
        int end = (1 << n) - 1;
        for (int j = 1; j <= end; ++j) {
            if (cnt[j] >= ans) continue;
            for (int i = 0; i < n; ++i) {
                if (((1 << i) & j) != 0) continue;
                int state = j | (1 << i);
                if (cnt[state] >= ans) continue;
                if (dp[state] != inf) continue;
                dp[state] = dp[j] % a[i];
                if (dp[state] == 0) ans = cnt[state];
            }
        }
        if (ans == inf) printf("-1
    ");
        else printf("%d
    ", ans);
    }
    
    int main() {
        init();
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code
  • 相关阅读:
    OpenCV 2.48配置
    win进入当前文件夹,启动当前文件夹的程序
    C++程序运行效率的10个简单方法
    银行国际清算业务平台架构
    股票证券交易系统架构分析与设计
    负载均衡|六种负载均衡算法
    Intelli IDEA快捷键(配合IdeaVim)(转)
    [易学易懂系列|golang语言|零基础|快速入门|(三)]
    [易学易懂系列|golang语言|零基础|快速入门|(二)]
    [易学易懂系列|golang语言|零基础|快速入门|(一)]
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6104160.html
Copyright © 2020-2023  润新知