微软2017年预科生计划在线编程笔试第二场-#1500 : EL SUENO

来源:互联网 发布:淘宝网12v 电池组 编辑:程序博客网 时间:2024/05/17 02:25

http://hihocoder.com/problemset/problem/1500

题意理解:一棵树,父亲只有在直接儿子被干掉的权重和大于某个数才能都被干掉,并且干掉一个点需要若干时间。权重《=20000, 节点《=2000,可以每一个节点都用裸的01背包做,注意背包容量可以超过,最后取min

急转弯:数据范围小,可以裸着做,另外注意min的取法。

算法:无

数据结构:树,但是和树的数据结构没有关系,只是用到了树的先考虑儿子,再考虑父亲的遍历(dfs)


注:python版本t了。。尴尬。。有好的优化希望能告诉我!


#include <iostream>#include <cstdio>#include <vector>using namespace std;const int maxn = 2000 + 100;const int MAXK = 20000 + 100;const int INF = 1e7;int need[maxn], have[maxn], tim[maxn];int n, rt;vector<int> G[maxn];int dfs(int u) {    if(G[u].size() == 0) return tim[u];    int f[MAXK];    f[0] = 0;    for(int i = 1; i < MAXK; i++) f[i] = INF;    for(int i = 0; i < G[u].size(); i++){        int v = G[u][i];        int t = dfs(v);        for(int j = need[u] - 1; j >= 0; j--) {            int no = min(MAXK - 1, j + have[v]);            f[no] = min(INF, min(f[no], f[j] + t));        }    }    int res = INF;    for(int i = need[u]; i < MAXK; i++) res = min(res, f[i]);    return res + tim[u];}int main() {    scanf("%d", &n);    rt = 1;    for(int i = 1; i <= n; i++) G[i].clear();    for(int i = 1; i <= n; i++) {        int a, b, c, d;        scanf("%d%d%d%d", &a, &b, &c, &d);        if(a == 0){            rt = i;        } else{            G[a].push_back(i);        }        need[i] = b;        have[i] = c;        tim[i] = d;    }    int res = dfs(rt);    if(res < INF) printf("%d\n", res);    else printf("-1");}
from __future__ import print_function##'python for tree and easy dp'__author__ = 'hjkruclion'import sysdef read_int():    return list(map(int, sys.stdin.readline().split()))MAXN = 20000 + 10INF = int(1e7)MAXP = 2000 + 100G = [[]for _ in range(MAXP)]# need = np.zeros([MAXP], np.int)# have = np.zeros([MAXP], np.int)# time = np.zeros([MAXP], np.int)need = [0 for _ in range(MAXP)]have = [0 for _ in range(MAXP)]time = [0 for _ in range(MAXP)]dp = [0 for _ in range(MAXP)]f = [0 for _ in range(MAXN + 10)]rt = 1N = read_int()[0]for i in range(1, N + 1):    fa, iN, ip, c = read_int()    if fa != 0:        G[fa].append(i)    else:        rt = i    need[i] = iN    have[i] = ip    time[i] = cdef dfs(u):    if len(G[u]) == 0:        return time[u]    # f = np.zeros([MAXN + 10], np.int)    for i in range(len(G[u])):        v = G[u][i]        dp[v] = dfs(v)    global f    f[0] = 0    for i in range(1, MAXN):        f[i] = INF    for i in range(len(G[u])):        v = G[u][i]        t = dp[v]        for j in reversed(range(need[u])):            no = min(need[u], j + have[v])            f[no] = min(INF, min(f[no], f[j] + t))    res = f[need[u]]    return min(INF, res + time[u])res = dfs(rt)if res < INF:    print(res)else:    print('-1')


 
阅读全文
0 0
原创粉丝点击