zoukankan      html  css  js  c++  java
  • dfs模拟暴力(ecfinal M题)

    https://codeforces.com/gym/102471/problem/M

    题意:给你集合A of {1,2,,n} , 求子集的最大分数

    给出a[1],a[2]...a[n] 和 b[1],b[2]...b[n].

    积分规则:

    1、初始分数为0.

    2、每一个加入集合的i加上a【i】分数

    3、集合中任意 (i,j) 满足i≥2, j≥2, i∈A and j∈A, 有 k>1 i的k次方=j, 就减掉b【j】分数。

    解法:sqrt(n)个数每个数存在次方关系的下标单拎出来,进行dfs暴力选与不选.

    #include <bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    #define cin(a) scanf("%d",&a)
    #define pii pair<int,int>
    #define ll long long
    #define gcd __gcd
    const int inf = 0x3f3f3f3f;
    const int maxn = 100100;
    const int M = 1e9+7;
    int n,k;
    ll a[maxn],b[maxn];
    bool vis[maxn];
    
    ll val[maxn],sub[maxn];
    bool slt[maxn];         //select
    ll mx;
    
    void dfs(int idx,ll sum)
    {
        if(idx == k)
        {
            mx = max(mx,sum);
            return;
        }
        slt[idx] = 1;      //选
        ll temp = sum+val[idx];
        for(int i = 1; i < idx; i++)
        {
            if(slt[i] && idx%i == 0) temp -= sub[idx];
        }
        dfs(idx+1,temp);
        slt[idx] = 0;       //回溯,不选
        dfs(idx+1,sum);
    }
    
    ll solve(int x)
    {
        k = 1;
        for(int i = x; i <= n; i*=x)
        {
            vis[i] = 1;
            val[k] = a[i];
            sub[k] = b[i];
            k++;
        }
        mx = 0;
        //memset(slt , false , sizeof(slt));
        dfs(0,0);
        return mx;
    }
    
    int main()
    {
    /*#ifdef ONLINE_JUDGE
    #else
        freopen("data.in", "r", stdin);
        //freopen("data.out", "w", stdout);
    #endif*/
        scanf("%d",&n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%lld",&a[i]);
        }
        for(int i = 1; i <= n; i++)
        {
            scanf("%lld",&b[i]);
        }
        ll ans = 0;
        for(int i = 2; i <= sqrt(n); i++)
        {
            if(!vis[i])ans += solve(i);//注意不要重复领出来,领一次就可以
        }
        for(int i = 1; i <= n; i++)
        {
            if(!vis[i]) ans += a[i];
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    使pre的内容自动换行
    textarea文本换行和页面显示换行符
    SQL查询包含汉字的行
    网站引导页插件intro.js 的用法
    jquery.cookie中的操作
    sql自动生成汉语拼音和首字母函数
    IE,Chrome滚动条样式CSS
    Vcenter server 5.5上传ISO镜像
    Vcenter server 5.5添加用户角色及分配权限
    Vcenter server 5.5安装部署
  • 原文地址:https://www.cnblogs.com/nonames/p/12156268.html
Copyright © 2011-2022 走看看