题解---洛谷P2230 [HNOI2002]Tinux系统
这是一道很水的黑题。
但是,本题的题意十分难懂。注意:样例输入是错的,最后一个4是多出来的。
整个题目的意思大概是:
一个节点最多可以有
其中,每个节点可以连出的边的权值是固定的,也就是说,每一个节点,它向儿子连边时,可以选择的边都是一样的。现在告诉你有
思路很简单,就是一个记忆化搜索,
然后转移也十分容易,对每条边,只有两种选择:
1.连叶子,直接加上
2.连非叶子节点,先加上这条边的贡献,然后在继续递归就可以了。
所以,我们只需要枚举第二种情况时,该节点下面放几个叶子节点就ok了
时间复杂度:
代码:
#include<bits/stdc++.h>
using namespace std;
int n,k,f[1005][1005],a[1005];
int dfs(int x,int y)
{
if(x==1)
{
f[x][y]=a[y];
return f[x][y];
}//只剩一个节点
if(y==k)return f[x][y]=dfs(x,1)+a[y]*x*x;
//只剩一条边,必须是连非叶子节点
if(f[x][y])return f[x][y];
f[x][y]=dfs(x-1,y+1)+a[y];//直接连叶子
for(int i=2;i<x;i++)//枚举
f[x][y]=min(f[x][y],dfs(x-i,y+1)+a[y]*i*i+dfs(i,1));
return f[x][y];
}
signed main()
{
cin>>n>>k;
for(int i=1;i<=k;i++)cin>>a[i];
sort(a+1,a+k+1);
printf("%d",dfs(n,1));
}