【GDSOI2017第三轮模拟】Travel Plan
来源:互联网 发布:内涵段子ios源码 编辑:程序博客网 时间:2024/05/03 16:58
Description
Sample Input
4
1 2
2 3
2 4
3 6
2 4
4 7
4 9
2
3 8
4 8
Sample Output
3
4
题解
首先观察一下这个范围,发现cost很大,但是value很小,所以我们考虑围绕value来dp
容易发现每一次ban掉的是一颗子树,也就是dfs序中的一段,所以我们可以考虑对前缀做一次dp,对后缀做一次dp,然后再合并
设f[i][j]表示我先在做到第i个点,获得j贡献所需的最小的代价,这个转移显然
现在考虑怎么合并
对于一个点x,它ban掉的就是dfs序中的t—-t+size[t]-1这些点,所以我们可以直接用两个指针来把前后缀合并一下
但是这样做理论时间复杂度很高,所以要注意一些优化
贴代码
const mc=4000000000;var a,b:array[0..1001,0..50000]of longword; new,size,co,va,s1,s2:array[0..1005]of longint; map:array[0..1005,0..1005]of integer; i,j,k,l,n,x,y,now,o,q,t1,t2,ans:longint; z,ct:int64;function min(x,y:longword):longword;begin if x<y then exit(x) else exit(y);end;procedure dfs(x,y:longint);var i:longint;begin inc(now); new[x]:=now; size[now]:=1; for i:=1 to map[x,0] do if map[x,i]<>y then begin dfs(map[x,i],x); size[new[x]]:=size[new[x]]+size[new[map[x,i]]]; end;end;begin assign(input,'plan.in'); reset(input); assign(output,'plan.out'); rewrite(output); readln(n); for i:=1 to n-1 do begin readln(x,y); inc(map[x,0]); map[x,map[x,0]]:=y; inc(map[y,0]); map[y,map[y,0]]:=x; end; dfs(1,0); for i:=1 to n do readln(va[new[i]],co[new[i]]); now:=0; for i:=1 to 50000 do a[0,i]:=mc; for i:=1 to n do begin now:=now+va[i]; s1[i]:=now; for j:=now downto va[i] do begin a[i,j]:=a[i-1,j]; if a[i,j]=0 then a[i,j]:=mc; a[i,j]:=min(a[i,j],a[i-1,j-va[i]]+co[i]); end; for j:=va[i]-1 downto 1 do begin a[i,j]:=a[i-1,j]; if a[i,j]=0 then a[i,j]:=mc; end; ct:=mc; for j:=now downto 1 do begin if a[i,j]<ct then ct:=a[i,j]; a[i,j]:=ct; end; end; now:=0; for i:=1 to 50000 do b[n+1,i]:=mc; for i:=n downto 1 do begin now:=now+va[i]; s2[i]:=now; for j:=now downto va[i] do begin b[i,j]:=b[i+1,j]; if b[i,j]=0 then b[i,j]:=mc; b[i,j]:=min(b[i,j],b[i+1,j-va[i]]+co[i]); end; for j:=va[i]-1 downto 1 do begin b[i,j]:=b[i+1,j]; if b[i,j]=0 then b[i,j]:=mc; end; ct:=mc; for j:=now downto 1 do begin if b[i,j]<ct then ct:=b[i,j]; b[i,j]:=ct; end; end; readln(q); for o:=1 to q do begin readln(x,z); x:=new[x]; y:=x+size[x]; x:=x-1; t1:=0; t2:=s2[y]; ans:=0; while t1<=s1[x] do begin while (a[x,t1]+b[y,t2]>z) and (t2>0) do dec(t2); if a[x,t1]>z then break; if t1+t2>ans then ans:=t1+t2; inc(t1); end; writeln(ans); end; close(input); close(output);end.
0 0
- 【GDSOI2017第三轮模拟】Travel Plan 背包
- 【GDSOI2017第三轮模拟】Travel Plan
- [JZOJ5081]. 【GDSOI2017第三轮模拟】Travel Plan
- 【GDSOI2017第三轮模拟】Travel Plan(DP)
- 【JZOJ5081】【GDSOI2017第三轮模拟】Travel Plan
- 【jzoj5081】【GDSOI2017第三轮模拟】【Travel Plan】【动态规划】
- jzoj 5081. 【GDSOI2017第三轮模拟】Travel Plan 背包+dfs序
- 【GDSOI2017模拟】Travel Plan
- 【GDSOI2017第三轮模拟】Gift
- [JZOJ5082].【GDSOI2017第三轮模拟】Informatics Training
- [JZOJ5083].【GDSOI2017第三轮模拟】Gift
- 【JZOJ5082】【GDSOI2017第三轮模拟】Informatics Training
- 【jzoj5083】【GDSOI2017第三轮模拟】【Gift】【快速傅立叶变换】
- 【GDSOI2017第三轮模拟】Informatics Training(码农,平衡树)
- 【GDSOI2017第二轮模拟】树
- 【GDSOI2017第二轮模拟】树
- GDOI2017第三轮模拟总结
- GDOI第三轮模拟总结
- VM虚拟机 拷贝系统文件夹 不兼容
- 剑指offer——)旋转数组的最小数字
- lcs最长公共子序列
- BFS广度优先搜索 poj1915
- 详解冒泡排序--适用于初学者,包会
- 【GDSOI2017第三轮模拟】Travel Plan
- 全排列和去重全排列---递归实现
- wikia中所有页面的查看
- 设计模式之适配器模式
- OCR技术识别文档的技术
- .Net基础班第一天总结
- JAVA正则表达式基本运用
- Thief in a Shop CodeForces
- UCOS专业术语中英对译