HDU 5148 Cities 树形DP(背包)
2017-10-07 15:20
405 查看
HDU 5148
题意;n个点的树,第i条边长度为c[i],任意选中k个点为特殊点,这k个点中,任意两点间距离的期望值最小为多少?
n<=2000,k<=min(50,n) c[i]<=1e6.
k个点任意选两个有k^2种选法 (u,v)对期望贡献为 dis(u,v)/k^2 也就是说要求这min(k个点中任意两点距离累加和/k^2)
先考虑一个特殊的情况 当k==n时 树上任意两点距离的累加和.
若u的子树中,有x个节点被选中,则(u,v)边贡献为x*(k-x) (u下面每个节点都往u上方走k-x次)
设dp[u][x] 从u中选x个结点时,该子树对答案的贡献值最小为?
枚举子树u的子树v选多少个就好
dp[u][x]= min(dp[u][x], dp[u][x-y]+dp[v][y]+cost(u,v)*y*(k-y)*2ll).
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,ll> ii;
const int N=4e3+20;
const ll inf=2e17;
vector<ii> e
;
int n,k;
ll dp
[51];
void dfs(int u,int fa)
{
dp[u][0]=dp[u][1]=0;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i].first;
ll w=e[u][i].second;
if(v==fa)
continue;
dfs(v,u);
b919
for(int y=k;y>=0;y--)
{
for(int x=0;x<=y;x++)
dp[u][y]=min(dp[u][y],dp[u][y-x]+dp[v][x]+w*x*(k-x)*2ll);
}
}
}
int main()
{
int T,n,u,v;
ll w;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
e[i].clear();
for(int i=1;i<=n-1;i++)
{
scanf("%d%d%lld",&u,&v,&w);
e[u].push_back(ii(v,w));
e[v].push_back(ii(u,w));
}
for(int i=1;i<=n;i++)
for(int j=2;j<=n;j++)
dp[i][j]=inf;
dfs(1,-1);
cout<<dp[1][k]<<endl;
}
return 0;
}
题意;n个点的树,第i条边长度为c[i],任意选中k个点为特殊点,这k个点中,任意两点间距离的期望值最小为多少?
n<=2000,k<=min(50,n) c[i]<=1e6.
k个点任意选两个有k^2种选法 (u,v)对期望贡献为 dis(u,v)/k^2 也就是说要求这min(k个点中任意两点距离累加和/k^2)
先考虑一个特殊的情况 当k==n时 树上任意两点距离的累加和.
若u的子树中,有x个节点被选中,则(u,v)边贡献为x*(k-x) (u下面每个节点都往u上方走k-x次)
设dp[u][x] 从u中选x个结点时,该子树对答案的贡献值最小为?
枚举子树u的子树v选多少个就好
dp[u][x]= min(dp[u][x], dp[u][x-y]+dp[v][y]+cost(u,v)*y*(k-y)*2ll).
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,ll> ii;
const int N=4e3+20;
const ll inf=2e17;
vector<ii> e
;
int n,k;
ll dp
[51];
void dfs(int u,int fa)
{
dp[u][0]=dp[u][1]=0;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i].first;
ll w=e[u][i].second;
if(v==fa)
continue;
dfs(v,u);
b919
for(int y=k;y>=0;y--)
{
for(int x=0;x<=y;x++)
dp[u][y]=min(dp[u][y],dp[u][y-x]+dp[v][x]+w*x*(k-x)*2ll);
}
}
}
int main()
{
int T,n,u,v;
ll w;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
e[i].clear();
for(int i=1;i<=n-1;i++)
{
scanf("%d%d%lld",&u,&v,&w);
e[u].push_back(ii(v,w));
e[v].push_back(ii(u,w));
}
for(int i=1;i<=n;i++)
for(int j=2;j<=n;j++)
dp[i][j]=inf;
dfs(1,-1);
cout<<dp[1][k]<<endl;
}
return 0;
}
相关文章推荐
- hdu 5148 Cities(树形背包)
- hdu 5148 cities 树形DP
- hdu 5148 树形dp,分组背包
- hdu 5148 Cities(树形dp)
- HDU 1561 The more, The Better 【树形dp + 依赖性01背包 】这类型入门题.
- HDU 3672 Caves ACM/ICPC 2007 成都区域赛 C 背包+树形DP
- 【HDU 4276】The Ghost Blows Light(树形DP,依赖背包)
- HDU 4044 GeoDefense 树形dp:树形背包★
- hdu 4003 Find Metal Mineral 树形DP:树形背包 ★ 好题
- 【树形DP】 HDOJ 5148 Cities
- HDU 3593 The most powerful force 树形DP(背包)
- hdu 1011 Starship Troopers (树形背包dp)
- [HDU] 1561 The more, The Better 树形DP加01分组背包
- hdu 1011 Starship Troopers (依赖背包 树形dp)
- hdu 1561 The more, The Better(树形dp,树上背包)
- hdu 5148 City (树形dp)
- HDU 1011 Starship Troopers 树形DP(0-1背包)
- HDU 1011 Starship Troopers 树形DP(0-1背包)
- HDU 1561 树形DP+有依赖的背包
- HDU 1561 —— The more, The Better(树形DP + 背包)