计蒜客 微软的员工福利(中等)
2016-07-09 17:46
169 查看
链接:https://nanti.jisuanke.com/t/11147
题意:中文题。
分析:中等难度n=100,我们可以树形dp,在计算节点i的时候我们暴力n^2枚举它和儿子们形成的min和max的所有可能,然后进行dp即可。在枚举的时候要考虑清楚。我写得比较麻烦。
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=110; const int MAX=1000000100; const int mod=100000000; const int MOD1=1000000007; const int MOD2=1000000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=1000000007; const int INF=1000000010; const double pi=acos(-1.0); typedef double db; typedef unsigned long long ull; ll d[2*N][2],a [2],dp [2]; int tot,u ,v[2*N],pre[2*N]; void add(int x,int y) { v[tot]=y;pre[tot]=u[x];u[x]=tot++; } void dfs(int x,int f) { int i,j,h,g,k=0,bo; ll mi,mx,tot; for (i=u[x];i!=-1;i=pre[i]) { if (v[i]==f) continue ;dfs(v[i],x); } d[k][0]=a[x][0];d[k][1]=x;k++; d[k][0]=a[x][1];d[k][1]=x;k++; for (i=u[x];i!=-1;i=pre[i]) { if (v[i]==f) continue ; d[k][0]=a[v[i]][0];d[k][1]=v[i];k++; d[k][0]=a[v[i]][1];d[k][1]=v[i];k++; } dp[x][0]=dp[x][1]=-INF; for (i=0;i<k;i++) for (j=i;j<k;j++) if (i!=(j^1)) { bo=1;tot=0;g=-1; if (d[i][1]==x) g=i&1; if (d[j][1]==x) g=j&1; mi=min(d[i][0],d[j][0]); mx=max(d[i][0],d[j][0]); if (d[i][1]!=x) tot+=dp[d[i][1]][i&1]; if (d[j][1]!=x&&i!=j) tot+=dp[d[j][1]][j&1]; for (h=2;h<k;h+=2) if (d[h][1]!=d[i][1]&&d[h][1]!=d[j][1]) { if ((a[d[h][1]][0]<mi&&a[d[h][1]][1]>mx)||(a[d[h][1]][0]>mx)||(a[d[h][1]][1]<mi)) { bo=0;break ; } else if (a[d[h][1]][0]<mi) tot+=dp[d[h][1]][1]; else if (a[d[h][1]][1]>mx) tot+=dp[d[h][1]][0]; else tot+=max(dp[d[h][1]][0],dp[d[h][1]][1]); } if (bo) { if ((a[x][0]<mi&&a[x][1]>mx)||(a[x][1]<mi)||(a[x][0]>mx)) ; else if (a[x][0]<mi) { tot+=a[x][1];dp[x][1]=max(dp[x][1],tot-((mx-mi+999)/1000)*666*x); } else if (a[x][1]>mx) { tot+=a[x][0];dp[x][0]=max(dp[x][0],tot-((mx-mi+999)/1000)*666*x); } else { if (g!=-1) dp[x][g]=max(dp[x][g],tot+a[x][g]-((mx-mi+999)/1000)*666*x); else { dp[x][0]=max(dp[x][0],tot+a[x][0]-((mx-mi+999)/1000)*666*x); dp[x][1]=max(dp[x][1],tot+a[x][1]-((mx-mi+999)/1000)*666*x); } } } } } int main() { int i,n,x,y; scanf("%d", &n); for (i=1;i<=n;i++) { scanf("%lld%lld", &a[i][0], &a[i][1]); if (a[i][0]>a[i][1]) swap(a[i][0],a[i][1]); } tot=0;memset(u,-1,sizeof(u)); for (i=1;i<n;i++) { scanf("%d%d", &x, &y); add(x,y);add(y,x); } dfs(1,1); printf("%lld\n", max(dp[1][0],dp[1][1])); return 0; }
相关文章推荐
- html5与html4的区别
- div 显示滚动条
- scala学习笔记--高阶函数
- SpringMVC 注解
- Java中原子操作类原则
- ggplot_坐标轴
- hdu 4740 The Donkey of Gui Zhou dfs 搜索 解题报告
- 学习笔记:用决策树预测隐形眼镜类型
- [从头读历史] 第295节 神之物语 结语:为什么会有希腊神话
- U盘 格式化 ext3 ext4
- TextView 加下划线的2种方式
- [Leetcode]102. Binary Tree Level Order Traversal
- java 多线程:原子性
- Unity应用发布如何在本地查看Debug输出?
- SDB-Schedule 简洁计划任务框架
- Java基础知识一
- ibatis升级mybatis的步骤
- 计算机的组成 —— 鼠标
- js中的字典
- 面向对象总结