URAL 1018
来源:互联网 发布:电商和微商的区别 知乎 编辑:程序博客网 时间:2024/05/16 09:35
题目大意:给一棵共有N个枝条的二叉苹果树,每个枝上有apple[i][j]个苹果,求保留Q个枝条时,能够留下的最大苹果数。
Time Limit:1000MS Memory Limit:16384KB 64bit IO Format:%I64d & %I64u
数据规模:2<=N<=100,1<=Q<=N-1,0<applle[i][j]<=30000。
理论基础:无。
题目分析:树dp。我们首先将所有的苹果转移到朝向叶子节点方向的节点。再添加一个虚拟的枝条,由虚拟根节点0指向根节点,这样方便后续的dp操作。
用dp[i][j]表示以i为根节点的子树,保留j个枝条时所能留下的最大苹果数。tree[i]表示编号为i的节点。
那么状态转移方程dp[i][j]=max(dp[tree[i].l][j-k]+dp[tree[i].r][k-1],(0<=k<j))+tree[i].value。
节点中存放的数据有,左儿子,右儿子,和苹果的数值。
采用记忆化搜索dp即可。答案即为:dp[1][++Q]的值。
代码如下:
#include<iostream>#include<cstring>#include<string>#include<cstdlib>#include<cstdio>#include<cmath>#include<algorithm>#include<queue>#include<ctime>#include<vector>using namespace std;typedef double db;#define DBG 1#define maa (1<<31)#define mii ((1<<31)-1)#define ast(b) if(DBG && !(b)) { printf("%d!!|\n", __LINE__); while(1) getchar(); } //调试#define dout DBG && cout << __LINE__ << ">>| "#define pr(x) #x"=" << (x) << " | "#define mk(x) DBG && cout << __LINE__ << "**| "#x << endl#define pra(arr, a, b) if(DBG) {\ dout<<#arr"[] |" <<endl; \ for(int i=a,i_b=b;i<=i_b;i++) cout<<"["<<i<<"]="<<arr[i]<<" |"<<((i-(a)+1)%8?" ":"\n"); \ if((b-a+1)%8) puts("");\}template<class T> inline bool updateMin(T& a, T b) { return a>b? a=b, true: false; }template<class T> inline bool updateMax(T& a, T b) { return a<b? a=b, true: false; }typedef long long LL;typedef long unsigned int LU;typedef long long unsigned int LLU;#define N 105#define Q 105struct treeNode{ int lc,rc,value;}tree[N];int dp[N][Q],apple[N][N],n,q;bool visit[N];void maketree(int root){ visit[root]=true; for(int i=1;i<=n;i++) { if(!visit[i]&&apple[root][i]!=-1) { if(tree[root].lc==0)tree[root].lc=i; else tree[root].rc=i; tree[i].value=apple[root][i]; maketree(i); } }}void init(){ memset(tree,0,sizeof tree); memset(dp,-1,sizeof dp); memset(visit,false,sizeof visit); memset(apple,-1,sizeof apple);}int treedp(int root,int pdt){ if(root==0||pdt==0)return 0; if(dp[root][pdt]!=-1)return dp[root][pdt]; int maxn=maa,lans,rans; for(int i=0;i<pdt;i++) { lans=treedp(tree[root].lc,i); rans=treedp(tree[root].rc,pdt-i-1); if(lans+rans>maxn)maxn=lans+rans; } return dp[root][pdt]=maxn+tree[root].value;}int main(){ init(); scanf("%d%d",&n,&q); for(int i=1;i<n;i++) { int l,r,v; scanf("%d%d%d",&l,&r,&v); apple[l][r]=apple[r][l]=v; } maketree(1); printf("%d\n",treedp(1,++q));return 0;}
其中,root为0的时候或者pdt为0的时候,无论怎样都不会留下苹果。
by:Jsun_moon http://blog.csdn.net/jsun_moon
- Ural 1018
- URAL 1018
- URAL 1018
- 【树状DP】ural 1018
- Ural 1018 树dp
- ural 1018(树形dp)
- ural 1018 二叉苹果树
- ural 1018 二*苹果树
- URAL
- 【ural】
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- Oracle scheduler - 调度程序概念
- linux CURL
- NUnit在VS2008下的使用
- 规避安卓4.0调试白名单的方法
- while循环输入cin ,scanf()
- URAL 1018
- 黑马程序员--09.动态与代理AOP--06【动态代理实例化的过程升级--目标对象+系统功能的参数化】【实现类似Spring的可配置AOP框架】
- 交通灯管理系统
- TCP 协议小研究
- UVA10917 A Walk Through the Forest
- 树型动态规划小练
- Unique Paths II
- Files 的值“<<<<<<< .mine”无效。路径中具有非法字符。
- Axis2开发环境的搭建