捡金子

news/2024/11/30 1:30:45/

D e s c r i p t i o n Description Description

从前有一个迷宫,迷宫的外形就像一棵带根树,每个结点(除了叶子结点外)恰好有 KK 个儿子。

一开始你在根结点,根结点的 KK 个儿子分别标记为‘A’, ‘B’, ‘C’….,而结点‘A’的 KK 个儿子结点分别标记为‘AA’,‘AB’,‘AC’……,依此类推。这棵树一共有 LL 层。

现在你事先知道 MM 个结点中有金子,并且你可以派出 NN 个机器人去收集金子。首先你可以分别指定每一个机器人的目标结点,于是这些机器人就会收集从根结点到其目标结点这条路径上(包括目标结点)所有的金子,但是每个位置的金子只能被收集一次。

现在你需要制定一个目标的分配方案,使得收集到的金子最多。

I n p u t Input Input

输入的第一行有 4 个整数:M,K,L,N。对应题目描述中的参数。

接下来 M 行,每行是一个字符串,表示所对应的结点上有金子。

O u t p u t Output Output

输出利用 N 个机器人所能捡到时最多几个结点上的金子。

S a m p l e Sample Sample I n p u t Input Input#1
5 3 3 1
ACC
ACB
AB
AC
A
S a m p l e Sample Sample I n p u t Input Input#2
5 3 3 1
ACC
ACB
AB
AC
A
S a m p l e Sample Sample O u t p u t Output Output#1
3
S a m p l e Sample Sample O u t p u t Output Output#2
4

H i n t Hint Hint

对于 20 % 20\% 20% 的数据,有 1 ≤ M ≤ 20 1\le M\le 20 1M20
对于 40 % 40\% 40% 的数据,有 1 ≤ M ≤ 2000 1\le M\le 2000 1M2000
对于 100%100% 的数据,有 1 ≤ M ≤ 50000 , 1 ≤ K ≤ 26 , 1 ≤ L ≤ 50 , 1 ≤ N ≤ 10 1\le M\le 50000, 1\le K\le 26, 1\le L\le 50, 1\le N\le 10 1M50000,1K26,1L50,1N10

T r a i n Train Train o f of of T h o u g h t Thought Thought

先将含有金子的点建一棵树
就是按原先的父子或爷爷和子孙的关系建树
没有金子的点可以不用加进树里面
然后用一个树形DP
f [ i ] [ j ] f[i][j] f[i][j]为前 i i i个点派出 j j j个机器人能捡多少金子

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;int h[50005], F[50005][15], T[50005];
int sum, n, m, l, r, t;
string A[50005];
string s;struct wh_
{int w, h;
}wh[50005];void hw(int x, int y)
{wh[++t] = (wh_){y, h[x]}, h[x] = t;}int Find(string k)//二分找父辈
{l = 1, r = n;while(l < r){int mid = (l + r) / 2;if(A[mid] < k)l = mid + 1;else r = mid;}return (A[r] == k) ? r : 0;//判断是否有这一个父辈
}void DP(int k)
{for(int l = h[k]; l; l = wh[l].h){DP(wh[l].w);for(int i = m; i >= 1; --i)for(int j = 1; j <= i; ++j)F[k][i] = max(F[k][i], F[wh[l].w][j] + F[k][i - j]);}for(int i = 1; i <= m; ++i)F[k][i] += T[k];
}int main()
{scanf("%d%d%d%d", &n, &l, &r, &m);for(int i = 1; i <= n; ++i)cin>>A[i], A[i] = ' ' + A[i];n++;A[n] = " ";sort(A + 1, A + n + 1);//排个序for(int i = 2; i <= n; ++i){int j = 0; s = A[i];while(j == 0)//找父辈{s.erase(s.length() - 1, 1);j = Find(s);}hw(j, i);//建树T[i] = 1;//这个点有一个金子}DP(1);printf("%d", F[1][m]);return 0;
}

http://www.ppmy.cn/news/455245.html

相关文章

现在捡芝麻都需要有见识吗?

俺爸每次在说教时候会说&#xff0c;就没看你读过一本完整的书&#xff0c;哪怕一本杂志。其实也不是没有读过&#xff0c;只不过读的少。 这几天看了硅谷来信第二十封&#xff0c;讲的是芝麻和西瓜的故事。道理简单&#xff0c;但做起来难。 人总是在芝麻与西瓜之间患得患失&a…

捡捡拾拾

被质问&#xff0c;你是不是一个真正的PHPer。我说&#xff0c;我第一门用于开发网站的语言就是PHP&#xff0c;没有什么好质疑的&#xff0c;都用了三年了&#xff0c;像是自己的第二语言一样。 要是这样为什么不去看看Perl呢&#xff1f;也许是另一种不错的选择。 PHP主要是架…

捡水果

蒜头在玩一款游戏&#xff0c;他在一个山顶&#xff0c;现在他要下山&#xff0c;山上有许多水果&#xff0c;蒜头每下一个高度就可以捡起一个水果&#xff0c;并且获得水果的能量。山的形状如图所示&#xff1a; 1 3 2 1 2 3 6 2 3 4 3 5 4 1 这是一个高度为 44 的山&#xff…

捡贝壳

捡贝壳 链接&#xff1a;https://ac.nowcoder.com/acm/contest/13504/E 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld 题目描述 小明来到一片海滩上&#xff0c;他很喜欢捡贝壳&…

捡金币

80分做法 DP本格子是从上个时间能够到达该格子的位置拓展出来的&#xff0c;可以闪现也可以步行&#xff08;注意可以不动&#xff09; 对这些状态取max即可 我们枚举时间&#xff0c;f[t][i][j][k]表示第t秒站在(i,j),已经用了k次闪现所获得的最大金币数 转移方程见代码&a…

捡点我的职业生涯

十五年前&#xff0c;你或许还不懂爱情&#xff0c;看Jack和Rose执手相看泪眼&#xff0c;只是蒙胧的心痛。十五年后&#xff0c;你会和谁一起走进影院&#xff0c;更会和谁一起&#xff0c;走到生命终点。 十五年前&#xff0c;我还不太懂技术&#xff0c;凭兴趣玩着C语言。十…

捡的

说好的教我一个简单的JS&#xff0c;时间一到立马陪嫂子打电话去了。哥&#xff0c;你果然是伯母捡来的。。。 转载于:https://www.cnblogs.com/bingg/p/5313851.html

捡到iphone6怎么解锁_捡到的iPhone被锁了怎么办

Apple ID 密码是用户要下载软件游戏时所需要的账户密码。一般卖家会帮用户 装些软件&#xff0c;但那是卖家的账户&#xff0c;用户不知道密码就不能自己下载软件。而且 IPHONE 手机不允许同一个机子出现 2 个账户下载的软件。所以最好的办法是 自己创建一个账户。 但自己下载前…