【2020杭电多校】 Lead of Wisdom 【暴搜】

这道题,我还以为是什么状压dp(看到dp头就疼)? 我是不是脑瘫了,一开始想过暴搜,就这?最坏时间复杂度跑一遍早就超过1e8了,一秒肯定跑不完,能过?弃了弃了,谁知道题目给了8000ms!!! 什么是问题!这就是问题!!!(郁闷)

题意 :
n个物体,k个种类,每个种类只能取一个,求最大属性值。

思路:
最坏时间复杂度 3^16 *10 *2
证明:k^(n/k),当k=3时最大,T为10,递归回溯过程需要乘2
既然时间够了,直接k层的数据进行搜索,每一层都只含有同一种类的信息,呢么我们只需要搜索出最大的一条链即可

举例:
在这里插入图片描述
参考代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
using namespace std;
typedef long long ll;
const int N = 3e5 + 5;
const ll maxn = 1e5 + 5;
struct Node
{
    ll a, b, c, d;
} p;
vector<Node> vec[65];
ll vis[65];
ll dfs(ll u, ll a, ll b, ll c, ll d, ll now)
{
    if (u == now + 1)
    {
        return (100 + a) * (100 + b) * (100 + c) * (100 + d);
    }
    ll n = vec[u].size();
    ll ans = 0;
    for (ll i = 0; i < n; i++)
    {
        p = vec[u][i];
        ans = max(ans, dfs(u + 1, a + p.a, b + p.b, c + p.c, d + p.d, now));
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    ll ans = 1;
    for (int i = 0; i < 16; i++)
        ans *= 3;
    cout << ans << endl;
    cin >> t;
    while (t--)
    {
        ll n, k, cnt = 0;
        cin >> n >> k;
        for (ll i = 1; i <= n; i++)
            vec[i].clear(), vis[i] = 0;
        for (ll i = 0; i < n; i++)
        {
            ll kind, a, b, c, d;
            cin >> kind >> a >> b >> c >> d;
            if (!vis[kind])
                vis[kind] = ++cnt;
            vec[vis[kind]].push_back({a, b, c, d});
        }
        cout << dfs(1, 0, 0, 0, 0, cnt) << endl;
    }
}

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/107567374
今日推荐