HDU 5735 Born Slippy
2016-07-24 16:54
351 查看
转载声明:http://blog.csdn.net/fsss_7/article/details/51999555(分析)
转载声明:http://blog.csdn.net/miracle_ma/article/details/52003773(参考代码)
题意:给定n个节点的一棵树, 每个节点都有权值, 现在s起点 ∈{1,2,3,4,5…n},
然后设 v1=s, 那么函数 f(s)=Wv1+∑(i=2)(m)Wvi opt Wvi-1 求的是以s为起点,祖先节点,组成一个序列使 f(s)最大,(这时的v2,v3..都还没确定的!) 不过所决定的序列(v1 < v2 < v3..( <代表右边顶点是左边的祖先)),然后输出S=(∑(i=1)(n) i*f(i))mod(1e9+7);
个人感觉:
推荐这两篇文章,第一篇文章题解,一看就几乎懂了..第二篇文章的推荐只是因为代码写得没那么晦涩难懂,我参考第二篇的代码+第一篇的代码理解而写出来..我也自己写写我的理解加深一下.
看到这道题,我们很容易就可以退出dp方程 dp[i]=max{dp[j]+wi opt wj} (j是i的父亲节点),如果按照这样子做dp的话,必然会超时(可以参考我的超时代码,很朴素的写法)
那么怎么优化呢,,这技巧我也没想过,反正我也不知道它的来历
首先我们设 w[i]=(a<<8) + b;(分成高8位和低8位)
那么转移方程就编程 dp[i]=max{dp[j]+(ai opt aj) + (bi opt bj) } 可是这样也没什么用啊,重头戏来了
我们先考虑一下,当前 w[i],会给后辈点带来什么影响,因为我们知道 后辈点的低8位在0-255的范围内,
我们设 f[a][b]=max{dp[i]+bi opt b}( b代表0-255) 那么我们就可以不管后辈点 低8位的关系,
假设当前 后辈点 为j , 那么我们只要枚举搞8位就可以得出答案了 此时 dp【j】=max{f[a][bj]+a opt aj}{a代表0-255)的所有高位就好了,
一定要!!注意a要存在才可能枚举呢,!因为这道样做法存在回溯,当前求出来的f在回溯的时候就不适用了,所以我们得用个Back保留一下这次的f才能对当前适用,具体看看代码咯.
分析:树形dp+ 优化
AC代码:
朴素超时代码:
转载声明:http://blog.csdn.net/miracle_ma/article/details/52003773(参考代码)
题意:给定n个节点的一棵树, 每个节点都有权值, 现在s起点 ∈{1,2,3,4,5…n},
然后设 v1=s, 那么函数 f(s)=Wv1+∑(i=2)(m)Wvi opt Wvi-1 求的是以s为起点,祖先节点,组成一个序列使 f(s)最大,(这时的v2,v3..都还没确定的!) 不过所决定的序列(v1 < v2 < v3..( <代表右边顶点是左边的祖先)),然后输出S=(∑(i=1)(n) i*f(i))mod(1e9+7);
个人感觉:
推荐这两篇文章,第一篇文章题解,一看就几乎懂了..第二篇文章的推荐只是因为代码写得没那么晦涩难懂,我参考第二篇的代码+第一篇的代码理解而写出来..我也自己写写我的理解加深一下.
看到这道题,我们很容易就可以退出dp方程 dp[i]=max{dp[j]+wi opt wj} (j是i的父亲节点),如果按照这样子做dp的话,必然会超时(可以参考我的超时代码,很朴素的写法)
那么怎么优化呢,,这技巧我也没想过,反正我也不知道它的来历
首先我们设 w[i]=(a<<8) + b;(分成高8位和低8位)
那么转移方程就编程 dp[i]=max{dp[j]+(ai opt aj) + (bi opt bj) } 可是这样也没什么用啊,重头戏来了
我们先考虑一下,当前 w[i],会给后辈点带来什么影响,因为我们知道 后辈点的低8位在0-255的范围内,
我们设 f[a][b]=max{dp[i]+bi opt b}( b代表0-255) 那么我们就可以不管后辈点 低8位的关系,
假设当前 后辈点 为j , 那么我们只要枚举搞8位就可以得出答案了 此时 dp【j】=max{f[a][bj]+a opt aj}{a代表0-255)的所有高位就好了,
一定要!!注意a要存在才可能枚举呢,!因为这道样做法存在回溯,当前求出来的f在回溯的时候就不适用了,所以我们得用个Back保留一下这次的f才能对当前适用,具体看看代码咯.
分析:树形dp+ 优化
AC代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ //#define OUT #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define Clear(x) memset(x,0,sizeof(x)) typedef long long ll; const int INF=0x3f3f3f3f; const int mod=1e9+7; const int maxn=(1<<16)+5; const int maxm=(1<<8)+5; ll w[maxn]; ll f[maxm][maxm]; ll dp[maxn]; ll Back[maxn][maxm]; vector<int> G[maxn]; string op; int T; int N; int opt(int a,int b) { if(op[0]=='A') return a&b; if(op[0]=='X') return a^b; return a|b; } void dfs(int u) { ll tmp=0; int a=w[u]>>8; int b=w[u]&255; for(int i=0;i<256;i++) { if(f[i][b]!=-1) tmp=max(tmp,f[i][b]+(opt(i,a)<<8)); } dp[u]=w[u]+tmp; for(int j=0;j<256;j++) { Back[u][j]=f[a][j]; } for(int j=0;j<256;j++) { f[a][j]=max(f[a][j],tmp+(opt(b,j))); } for(int j=0;j<G[u].size();j++) { dfs(G[u][j]); } for(int j=0;j<256;j++) f[a][j]=Back[u][j]; } int main() { #ifdef OUT freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout); #endif scanf("%d",&T); while(T--) { scanf("%d",&N); cin>>op; for(int i=1;i<=N;i++) { scanf("%I64d",&w[i]); G[i].clear(); } for(int i=2;i<=N;i++) { int x; scanf("%d",&x); G[x].push_back(i); } memset(f,-1,sizeof(f)); memset(dp,0,sizeof(dp)); dfs(1); ll ans=0; for(int j=1;j<=N;j++) { ans=(ans+j*dp[j])%mod; } printf("%I64d\n",ans); } return 0; }
朴素超时代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ //#define OUT #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define Clear(x) memset(x,0,sizeof(x)) typedef long long ll; const int INF=0x3f3f3f3f; int T; int N; const int maxn=1e5; const int mod=1e9+7; string str; int f[maxn]; int w[maxn]; ll dp[maxn]; int opt(int a,int b) { if(str[0]=='A') return a&b; if(str[0]=='O') return a|b; return a^b; } void init() { memset(f,-1,sizeof(f)); memset(dp,0,sizeof(dp)); } ll V(int s) { int tmp=f[s]; while(tmp!=-1) { dp[s]=max(dp[s],dp[tmp]+opt(w[s],w[tmp])); tmp=f[tmp]; //cout<<tmp<<endl; } return dp[s]; } int main() { #ifdef OUT freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout); #endif scanf("%d",&T); while(T--) { init(); scanf("%d",&N); cin>>str; ll ans=0; for(int i=1;i<=N;i++) scanf("%d",&w[i]); for(int i=2;i<=N;i++) { scanf("%d",&f[i]); } for(int i=1;i<=N;i++) { ans+=(i*(w[i]+V(i)))%mod; } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- 实现自己的C++ STL--vector容器
- hibernate学习之路
- bzoj 3672 [Noi2014]购票 (线段树+凸壳)
- Android中线程应用
- java构造器的作用
- Java异常处理-----自定义异常
- Java异常处理-----自定义异常
- Mybatis入门
- 刻录DVD_待整理
- Leetcode-add-two-numbers
- CentOS6.5配置01 -- LAMP(appache,mysql,php)安装
- CSS3基础
- 仿乐透购彩app(6)
- HDU 2298 Toxophily
- SpringMVC学习之路
- KMP
- 定义和声明以及extern、static关键字
- ImageView ScaleType属性
- SQL 中的 TRIM 函数
- thinkphp集成系列之短信验证码、订单通知