美团2021届秋季校园招聘笔试-小美的区域会议——人工加入限制+树形dp

Posted hans774882968

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了美团2021届秋季校园招聘笔试-小美的区域会议——人工加入限制+树形dp相关的知识,希望对你有一定的参考价值。

总结:集合划分的思想+树形dp+定义序关系(用于去重)

直接按树形dp想,没有思路,因为你强行记录所选取方案集合的权值最小和最大显然不可做。

此时考虑加入一些假设(限制)。假设当前枚举的点i是所选子树的点权最小的点(假设是最大的点也行)。不难发现遍历所有i对应的合法方案集合,是对所有合法方案的一个划分。以i为树根跑树形dp,保证所有选择的点的权值都在a[rt]~a[rt]+k即可。因为子树答案只会被使用一次,所以dp数组可以省略。时间复杂度:O(n^2)

但是我们还面临一个问题:如果一个合法方案有多个最小点权的点,则以上方法会重复统计。因此定义一个序关系(注:在单调栈相关的一些题目里也见过这种技巧,我把它叫做”非对称定义“。):当a[v] == a[rt],只有编号小于rt的那些点v对应的子树才能被选择。在此定义下,某个合法方案只会被编号最大的那个点权最小的点统计。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
#define re_(i,a,b) for(int i = (a);i < (b);++i)
#define dwn(i,a,b) for(int i = (a);i >= (b);--i)

const int N = 2e3 + 5;
const int mod = 1e9 + 7;

int n,k,a[N];vector<int> G[N];

void dbg(){puts("");}
template<typename T, typename... R>void dbg(const T &f, const R &... r) {
    cout << f << " ";
    dbg(r...);
}
template<typename Type>inline void read(Type &xx){
    Type f = 1;char ch;xx = 0;
    for(ch = getchar();ch < '0' || ch > '9';ch = getchar()) if(ch == '-') f = -1;
    for(;ch >= '0' && ch <= '9';ch = getchar()) xx = xx * 10 + ch - '0';
    xx *= f;
}

LL dfs(int u,int ufa,int rt){
    LL ans = 1;
    for(int v: G[u]){
        if(v == ufa) continue;
        if((a[v] == a[rt] && v < rt) || (a[rt] < a[v] && a[v] <= a[rt]+k)){
            (ans *= (1+dfs(v,u,rt))%mod) %= mod;
        }
    }
    return ans;
}

int main(int argc, char** argv) {
    read(n);read(k);
    re_(_,1,n){
        int p1,p2;read(p1);read(p2);
        G[p1].push_back(p2);
        G[p2].push_back(p1);
    }
    rep(i,1,n) read(a[i]);
    int ans = 0;
    rep(i,1,n) (ans += dfs(i,0,i)) %= mod;
    printf("%d\\n",ans);
    return 0;
}

以上是关于美团2021届秋季校园招聘笔试-小美的区域会议——人工加入限制+树形dp的主要内容,如果未能解决你的问题,请参考以下文章

JAVAvivo2021届秋季校招笔试在线编程

JAVAvivo2021届秋季校招笔试在线编程

字节秋季笔试四道编程题(2021-09-12)

米哈游2023秋季招聘正式开始~提前批有机会免笔试!

招5000人!美团2023届校园招聘全面启动

招5000人!美团2023届校园招聘全面启动