• 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
  • 相关阅读:
    uploadify
    mark down pad2
    yii1.1.3主从(多从)、读写分离配置
    yii多数据库
    Uploadify上传问题
    出现upstream sent too big header while reading response header from upstream错误
    Nginx 启动脚本/重启脚本
    VB6_小林的气象类模块
    进程与线程
    JDK动态代理与CGLib
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6104160.html
Copyright © 2020-2023  润新知