Milk Team Select 产奶比赛

Description

Farmer John’s N (\(1 \le N \le 500\)) cows are trying to select the milking team for the world-famous Multistate Milking Match-up (MMM) competition. As you probably know, any team that produces at least X (\(1 \le X \le 1,000,000\)) gallons of milk is a winner. Each cow has the potential of contributing between \(-10,000\) and \(10,000\) gallons of milk. (Sadly, some cows have a tendency to knock over jugs containing milk produced by other cows.) The MMM prides itself on promoting family values. FJ’s cows have no doubt that they can produce X gallons of milk and win the contest, but to support the contest’s spirit, they want to send a team with as many parent-child relationships as possible (while still producing at least X gallons of milk). Not surprisingly, all the cows on FJ’s farm are female. Given the family tree of FJ’s cows and the amount of milk that each would contribute, compute the maximum number of parent-child relationships that can exist in a winning team. Note that a set of cows with a grandmother-mother-daughter combination has two parent-child relationships (grandmother-mother, mother-daughter).

约翰的N(\(1 \le N \le 500\))头奶牛打算组队去参加一个世界级的产奶比赛(Multistate Milking Match-up,缩写为MMM).她们很清楚其他队的实力,也就是说,她们派出的队只要能产出至少X(\(1 \le X \le 1000000\))加仑牛奶,就能赢得这场比赛. 每头牛都能为集体贡献一定量的牛奶,数值在\(-10000\)到\(10000\)之间(有些奶牛总是想弄翻装着其他奶牛产的奶的瓶子).

MMM的举办目的之一,是通过竞赛中的合作来增进家庭成员之间的默契.奶牛们认为她们总是能赢得这场比赛,但为了表示对比赛精神的支持,她们希望在选出的队伍里能有尽可能多的牛来自同一个家庭,也就是说,有尽可能多对的牛有直系血缘关系(当然,这支队伍必须能产出至少X加仑牛奶).当然了,所有的奶牛都是女性,所以队伍里所有直系血亲都是母女关系. 约翰熟知所有奶牛之间的血缘关系.现在他想知道,如果在保证一支队伍能赢得比赛的情况下,队伍中最多能存在多少对血缘关系.注意,如果一支队伍由某头奶牛和她的母亲、她的外祖母组成,那这支队伍里一共有2对血缘关系(这头奶牛外祖母与她的母亲,以及她与她的母亲).

Input

Line 1: Two space-separated integers, N and X.

Lines 2..N+1: Line i+1 contains two space-separated integers describing cow i. The first integer is the number of gallons of milk cow i would contribute. The second integer (range 1..N) is the index of the cow’s mother. If the cow’s mother is unknown, the second number is 0. The family information has no cycles: no cow is her own mother, grandmother, etc.

第1行:两个用空格隔开的整数N和X.

第2到N+1行:每行包括两个用空格隔开的整数,第一个数为一只奶牛能贡献出的牛奶的加仑数,第二个数表示她的母亲的编号.如果她的母亲不在整个牛群里,那第二个数为0.并且,血缘信息不会出现循环,也就是说一头奶牛不会是自己的母亲或祖母,或者更高代的祖先.

Output

Line 1: The maximum number of parent-child relationships possible on a winning team. Print -1 if no team can win.

输出在一个能获胜的队伍中,最多可能存在的有血缘关系的牛的对数.如果任何一支队伍都不可能获胜,输出-1.

Sample Input

5 8
-1 0
3 1
5 1
-3 3
2 0

第一个数字代表这头奶的产量,第二个数字代表其父亲点是哪一个.

INPUT DETAILS: There are 5 cows. Cow 1 can produce -1 gallons and has two daughters, cow 2 and 3, who can produce 3 and 5 gallons, respectively. Cow 3 has a daughter (cow 4) who can produce -3 gallons. Then there’s cow 5, who can produce 2 gallons.

Sample Output

2

HINT

约翰一共有5头奶牛.第1头奶牛能提供-1加仑的牛奶,且她是第2、第3头奶牛的母亲.第2、第3头奶牛的产奶量务别为3加仑和5加仑.第4头奶牛是第3头奶牛的女儿,她能提供-3加仑牛奶.还有与其他牛都没有关系的第5头奶牛,她的产奶量是2加仑.

最好的一支队伍包括第1,2,3,5头奶牛.她们一共能产出\(-1+3+5+2=9 \ge 8\)加仑牛奶,并且这支队伍里有2对牛有血缘关系(1-2和1-3).如果只选第2,3,5头奶牛,虽然总产奶量会更高(10加仑),但这支队伍里包含的血缘关系的对数比上一种组合少(队伍里没有血缘关系对).

Source

Gold


思路

很明显,这是一道动态规划题(看着很像背包嘛)那我们要用什么作为下表呢?

  1. 以牛奶量:牛奶量的数据范围较大,最多只能开一维数组(除非你开滚动数组)。总体来说较难考虑。
  2. 以关系数:关系数最多只有 N - 1 对,可以给每头牛开一个 MAXN 的数组,看起来更行得通。。。

还有,因为要考虑关系数的转换问题,所以还有开一维[0/1]表示这头牛取不取。

我们发现,这些关系是无环的,或者说这是一个森林(本来我想用拓扑排序,后来还是放弃了。。。),所以可以再建立一头“牛祖先”,连接原来所有祖先,构成一棵树(即无母亲的节点都认0为母亲)。

对于样例,可以构成如图的一棵树:

整理一下,刚才讲到建立一个 \(int f[MAXN][MAXN][2];\) 的数组,\(f[i][j][op]\)表示以第 i 个节点为根的树 共有 j 对关系,op = 1 时表示取这个节点,op = 0 时表示不取。

可以把 关系数 作为背包容量,牛奶量 作为 价值

用分组背包的方法来考虑。

具体的部分自己慢慢理解吧。

上代码——

代码

#include<cstdio>
#include<iostream>
using namespace std;
#define MAXN 505
#define INF 0x3f3f3f3f int N, X, ans;
int c[MAXN], t;
int head[MAXN], to[MAXN << 1], nxt[MAXN << 1], tot(0);
int f[MAXN][MAXN][2]; void Add( int x, int y ){
to[++tot] = y; nxt[tot] = head[x]; head[x] = tot;
} void DFS( int x, int fa ){
for ( int i = 1; i <= N; i++ ) f[x][i][0] = f[x][i][1] = -INF;//初始值均为负无穷
for ( int i = head[x]; i; i = nxt[i] ){
if ( to[i] == fa ) continue;
DFS( to[i], x );//先完成子节点
for ( int j = N; j >= 0; --j ){//分配的关系数
for ( int k = 0; k <= j; ++k ){//背包——
f[x][j][1] = max( f[x][j][1], f[x][j - k][1] + max( k == 0 ? -INF : f[to[i]][k - 1][1], f[to[i]][k][0] ) );
f[x][j][0] = max( f[x][j][0], f[x][j - k][0] + max( f[to[i]][k][1], f[to[i]][k][0] ) );
}
}
}
for ( int i = 0; i <= N; ++i ) f[x][i][1] += c[x];//若取这个节点,加上这个点的价值
} int main(){
scanf( "%d%d", &N, &X );
for ( int i = 1; i <= N; ++i ){
scanf( "%d%d", &c[i], &t );
Add( i, t ); Add( t, i );//链式前向星存边
}
DFS( 0, -1 );
int ans(N);
while( ans >= 0 ){
if ( f[0][ans][0] >= X ) break;
ans--;
}
printf( "%d\n", ans );
return 0;
}

「BZOJ1722」「Usaco2006 Mar」Milk Team Select产奶比赛 解题报告的更多相关文章

  1. bzoj1722: [Usaco2006 Mar] Milk Team Select 产奶比赛 树形dp

    题目链接 bzoj1722: [Usaco2006 Mar] Milk Team Select 产奶比赛 题解 dp[i][j][0 / 1] 以i为根的子数中 相邻点对选了j个的最大价值 代码 #i ...

  2. 1722: [Usaco2006 Mar] Milk Team Select 产奶比赛

    1722: [Usaco2006 Mar] Milk Team Select 产奶比赛 https://www.lydsy.com/JudgeOnline/problem.php?id=1722 分析 ...

  3. [BZOJ1722]Milk Team Select 产奶比赛

    Description Farmer John's N (1 <= N <= 500) cows are trying to select the milking team for the ...

  4. BZOJ1722 [Usaco2006 Mar] Milk Team Select 产奶比赛

    直接树形dp就好了恩 令$f[i][j][t]$表示以$i$为根的子树,选出来的点存在$j$对父子关系,$t$表示$i$这个点选或者没选,的最大产奶值 分类讨论自己和儿子分别有没有选,然后转移一下就好 ...

  5. 【Usaco2006Mar】Milk Team Select产奶比赛

    [思路分析] 比赛的时候想到了用我确实也想到了树形DP,但是状态没有确定对,连样例都没有过 PS:这是第二道发现还可以用状态作为答案最后输出的题目 正解:树形DP(背包) 按照读进来的数据,我们先建一 ...

  6. 「Mobile Testing Summit China 2016」 中国移动互联网测试大会-议题征集

    时至北京盛夏,一场由 TesterHome 主办的关于移动互联网测试技术的盛会正在紧锣密鼓的筹备中.只要你关注软件质量,热爱测试,期待学习,都欢迎你加入这次移动测试技术大会中和我们一起分享经验.探讨话 ...

  7. Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新

    当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...

  8. 【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)

    Lighting和Shading(2)镜面反射的控制和模拟次级表面散射技术 http://www.4gamer.net/games/216/G021678/20140703095/index_2.ht ...

  9. 「Windows MFC 」「Edit Control」 控件

    「Windows MFC 」「Edit Control」 控件

随机推荐

  1. 在线学编程!十大IT在线教育网站推荐

    在线学编程!十大IT在线教育网站推荐 1.CSDN学院(http://edu.csdn.net/) CSDN学院是CSDN推出的一个面向中国软件开发者和IT专业人员的技术教育服务平台.主要提供IT领域 ...

  2. oralce 分离表和索引

    总是将你的表和索引建立在不同的表空间内(TABLESPACES). 决不要将不属于ORACLE内部系统的对象存放到SYSTEM表空间里. 同时,确保数据表空间和索引表空间置于不同的硬盘上.   “同时 ...

  3. Jieba分词包(一)——解析主函数cut

    1. 解析主函数cut Jieba分词包的主函数在jieba文件夹下的__init__.py中,在这个py文件中有个cut的函数,这个就是控制着整个jieba分词包的主函数.    cut函数的定义如 ...

  4. js保存图片到手机相册

    /保存到相册 function savePic(){ var picurl= $("#picurl").attr("src"); //alert(picurl) ...

  5. functiils.lru_cache缩短递归时间

    力扣上看到一道题: 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 使用普通递归解决,超出时间限 ...

  6. Python--day69--ORM正反向查找(外键)

    ForeignKey操作 正向查找 对象查找(跨表) 语法: 对象.关联字段.字段   示例: book_obj = models.Book.objects.first() # 第一本书对象 prin ...

  7. Python--day69--ORM多对多查询

    ManyToManyField class RelatedManager "关联管理器"是在一对多或者多对多的关联上下文中使用的管理器. 它存在于下面两种情况: 外键关系的反向查询 ...

  8. linux 使用 ioctl 参数

    在看 scull 驱动的 ioctl 代码之前, 我们需要涉及的另一点是如何使用这个额外的参数. 如果它是一个整数, 就容易: 它可以直接使用. 如果它是一个指针, 但是, 必须小心些. 当用一个指针 ...

  9. gulp4.0基本配置,超简单!

    最近复习了一下gulp,目前是4.0版本. 下图是基本目录结构,文件里面的内容可以随意添加,超详细简洁啊! 直接上代码(依赖未完全使用): 项目的所有依赖都可以安装,每个都有详细的注释. const ...

  10. jQuery 工具类函数-检测对象是否为空

    在jQuery中,可以调用名为$.isEmptyObject的工具函数,检测一个对象的内容是否为空,如果为空,则该函数返回true,否则,返回false值,调用格式如下: $.isEmptyObjec ...