zoukankan      html  css  js  c++  java
  • Codeforces Round #360 (Div. 2) D 数学推导 E dp

    Codeforces Round #360 (Div. 2)

    A  ==

    B  水,但记一下: 

    第 n 个长度为偶数的回文数是  n+reverse(n)。

    C    dfs 01染色,水

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005;
    
    int n, m;
    struct Edge{int to,next; } e[N<<1];
    int tot, head[N], mp[N<<1];
    void Addedge(int u, int v) {
        mp[tot]=tot;    e[tot]={v, head[u] }; head[u]=tot++;
        mp[tot]=tot-1;  e[tot]={u, head[v] }; head[v]=tot++;
    }
    bool vis[N];
    int cnt1, mark[N];
    bool dfs(int u, bool flag)
    {
        vis[u]=1,  mark[u]=flag;
        if(mark[u]==0) ++cnt1;
        for(int i=head[u]; i!=-1; i=e[i].next)
            if(mark[e[i].to]==-1)
            {
                bool flag1=dfs(e[i].to, flag^1);
                if(flag1==false) return false;
            }
            else if(mark[e[i].to]==flag)
            {
                return false;
            }
        return true;
    }
    int main()
    {
        scanf("%d %d", &n, &m);
        int u, v;
        mes(head, -1);  mes(mark, -1);
        rep(i,1,m) {
            scanf("%d %d", &u, &v);
            Addedge(u, v);
        }
        rep(i,1,n) if(vis[i]==0) {
            bool flag=dfs(i, 0);
            if(flag==false) return 0*printf("-1");
        }
        printf("%d
    ", cnt1);
        rep(i,1,n) if(mark[i]==0) printf("%d ", i);
        puts("");
        printf("%d
    ", n-cnt1);
        rep(i,1,n) if(mark[i]==1) printf("%d ", i);
        puts("");
    
        return 0;
    }
    View Code

    D    数学推导

    题意:给出 k 但不告诉你 x ,并且告诉你 n 个 ci ,你也知道 x%ci, 问 x%k 是否能唯一确定。
    tags: 这个题,完全懵的,题目意思都看不懂。。

    反过来想,如果 x%k 不能唯一确定,则必定存在 x1、x2 (x1>x2) 满足 x1%ci==x2%ci,且 x1%k != x2%k 。 也就是 (x1-x2)%ci==0,且 (x1-x2)%k != 0 , 进一步说就是: lcm(ci) %(x1-x2)==0 且 lcm(ci)%k != 0 , 也就是 lcm(ci)%k != 0 。   这样就得出命题: 如果 x%k 不能唯一确定,那么 lcm(ci)%k != 0。  变为逆否命题即:如果 lcm(ci)%k==0 ,那么 x%k 能唯一确定。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 1000005;
    
    ll  n, k, c[N];
    int main()
    {
        scanf("%lld %lld", &n, &k);
        ll  lcm1=1;
        rep(i,1,n) {
            scanf("%lld", &c[i]);
            if(lcm1) ( lcm1 = c[i]*lcm1/__gcd(c[i], lcm1) ) %=k;
            else  break;
        }
        if(lcm1%k==0) puts("Yes");
        else puts("No");
    
        return 0;
    }
    View Code

    E     三维dp

    题意: 给你一些硬币,让你选出一个子集的总价值和为 k,然后对于一个选出的子集,除了可以组成k以外,还可以在选出的子集中选出一些其他的价值。问你所有的选出的子集一共可以得到多少种价值。 

    tags:  CF 评测机我是服气的,1.25e8 两秒的时限,这都能过。。

    dp[i][j][k] 表示前 i 个硬币,当前遍历到第 i 个硬币时,选出的集合的总和是 j ,子集合的和是 k 的方案数。 递推式: dp[i][j][k] = dp[i-1][j]+dp[i-1][j-ci][k]+dp[i-1][j-ci][k-ci] 。(即遍历到第 i 个硬币时,可以不选它,也可以选它加入到总集合,但不加入子集合, 也可选它加入到两个集合)

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 501;
    
    int n, ki, c[N];
    ll  dp[2][N][N];
    int main()
    {
        scanf("%d %d", &n, &ki);
        rep(i,1,n) scanf("%d", &c[i]);
        int cnt=0;      dp[cnt^1][0][0] = 1;
        rep(i,1,n)
        {
            rep(j,0,ki) rep(k,0,j)
            {
                dp[cnt][j][k]=0;
                dp[cnt][j][k] = max(dp[cnt][j][k], dp[cnt^1][j][k]);
                if(j-c[i]>=0) dp[cnt][j][k] = max(dp[cnt][j][k], dp[cnt^1][j-c[i]][k]);
                if(k-c[i]>=0) dp[cnt][j][k] = max(dp[cnt][j][k], dp[cnt^1][j-c[i]][k-c[i]]);
            }
            cnt ^= 1;
        }
        cnt ^= 1;
        int ans=0;
        rep(k,0,ki) if(dp[cnt][ki][k]) ++ans;
        printf("%d
    ", ans);
        rep(k,0,ki) if(dp[cnt][ki][k]) printf("%d ", k);
        puts("");
    
        return 0;
    }
    View Code
  • 相关阅读:
    PHP 使用 Redis
    Redis /etc/redis.conf 常用配置
    Redis 常用操作
    Redis 操作哈希数据
    Redis 操作有序集合数据
    Redis 操作集合数据
    Redis 操作列表数据
    Redis 操作字符串数据
    Redis 安装
    Redis 简介
  • 原文地址:https://www.cnblogs.com/sbfhy/p/7258027.html
Copyright © 2011-2022 走看看