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;
    }
    
  • 相关阅读:
    汉字获取首字母
    .net 实现对DNS服务器的管理
    css使图片变灰
    javascript实现文本框只能输入数字和字母
    解决Outlook不能打开的问题
    javascript实现弹出式登录界面
    asp.net防盗链技术
    javascript中replace()(转帖)
    chm文件无法显示问题
    使用Lucene.NET进行分词、搜索
  • 原文地址:https://www.cnblogs.com/nonames/p/12156268.html
Copyright © 2011-2022 走看看