挖宝藏 treasures
来源:互联网 发布:r计算相关系数矩阵 编辑:程序博客网 时间:2024/06/03 02:56
挖宝藏
treasures/.in/.out/.pas/.exe
【题意】
在一个无限大的二维网格中有n处宝藏,给出每个宝藏的坐标(x[i],y[i])以及价值p[i],已知挖掘一个网格(x,y)需要满足<该点纵坐标y=-1>或<(x-1,y+1)(x,y+1)(x+1,y+1)三个网格都被挖掘过>,挖掘一个网格需要1代价,挖掘有宝藏的网格则可得到该宝藏的价值,求最大收益
【输入】
第一行一个数字n(n<=1000)
接下来n行每行三个数字表示一个宝藏(每个宝藏的横坐标大于等于-10000小于等于10000,纵坐标小于等于-1,价值不超过大于等于1小于等于1000000)
【输出】
输出一个数表示最大收益
动态规划
首先说一个思路上的误区,我看到这道题发现要挖掘一个点需要挖掘它之下的一个三角形,首先想到的是一行一行的处理,这不科学。
这道题应当竖着一列一列的处理,f[x][y]表示处理到第x行,最低点在y的最大收益
那么f[x][y]=max(f[x-1][y-1],f[x-1][y],f[x-1][y+1])+p[x][y] (p[x][y]表示第p列在-1..y的所有宝藏价值及挖掘费用之差)
由于x范围为20000,y范围为10000,20000*10000=200000000,时间上不允许
由于点比较少,所以采取离散化
首先枚举x坐标,然后求出在该列上的三角形边界上的点的纵坐标,排序后求p,便可以dp了
n<=1000的,相比于y优化了10倍,便可在规定时限内通过所有数据
program treasures;type point=record x,y,p:longint; end; arr=array [-10001..0] of longint;var tot,n,i,j,k,s,e,o,sum:longint; dl,root:array [0..1001] of point; zero:arr; f:array [0..1] of arr;procedure swap (var a,b:longint);inline;var i:longint;begin i:=a; a:=b; b:=i;end;procedure qsort (s,e:longint);var i,j,k:longint;begin if s>=e then exit; i:=s; j:=e; k:=dl[(s+e) div 2].y; while i<=j do begin while dl[i].y>k do inc(i); while dl[j].y<k do dec(j); if i>j then break; swap(dl[i].x,dl[j].x); swap(dl[i].y,dl[j].y); swap(dl[i].p,dl[j].p); inc(i); dec(j); end; qsort(s,j); qsort(i,e);end;begin assign(input,'treasures.in'); reset(input); assign(output,'treasures.out'); rewrite(output); read(n); s:=maxlongint; e:=-maxlongint; for i:=1 to n do begin read(root[i].x,root[i].y,root[i].p); if root[i].x+(root[i].y+1)<s then s:=root[i].x+(root[i].y+1); if root[i].x-(root[i].y+1)>e then e:=root[i].x-(root[i].y+1); end; for i:=-10000 to 0 do zero[i]:=-maxlongint div 10; zero[0]:=0; o:=0; f[o]:=zero; tot:=0; for i:=s to e+1 do begin o:=1-o; f[o]:=zero; tot:=0; for j:=1 to n do if (root[j].x+(root[j].y+1)<=i) and(root[j].x-(root[j].y+1)>=i) then begin inc(tot); dl[tot].x:=i; dl[tot].y:=root[j].y+abs(root[j].x-i); if root[j].x=i then dl[tot].p:=root[j].p else dl[tot].p:=0; end; qsort(1,tot); f[o,0]:=f[1-o,0]; if f[1-o,-1]>f[o,0] then f[o,0]:=f[1-o,-1]; k:=0; sum:=0; for j:=1 to tot do begin sum:=sum+dl[j].p+dl[j].y-k; k:=dl[j].y; if f[o,dl[j].y]<f[1-o,dl[j].y-1]+sum then f[o,dl[j].y]:=f[1-o,dl[j].y-1]+sum; if f[o,dl[j].y]<f[1-o,dl[j].y]+sum then f[o,dl[j].y]:=f[1-o,dl[j].y]+sum; if f[o,dl[j].y]<f[1-o,dl[j].y+1]+sum then f[o,dl[j].y]:=f[1-o,dl[j].y+1]+sum; end; end; writeln(f[o,0]); close(input); close(output);end.
- 挖宝藏 treasures
- 挖宝藏啦!!
- 【NOI2014】挖宝藏(treasure)
- 【JZOJ 3737】挖宝藏
- JZOJ3737 挖宝藏(treasure)
- 宝藏
- 宝藏
- 宝藏
- 宝藏
- 宝藏
- JS小游戏 挖宝藏v1.0
- 挖一个深坑在那里找寻宝藏
- 【JZOJ3737】【NOI2014模拟7.11】挖宝藏(treasure)
- 【NOI2014模拟7.11】挖宝藏(treasure)
- 【jzoj3737】【挖宝藏】【斯坦纳树】【状态压缩动态规划】
- 【NOI2014模拟7.11】【WC2008游览计划加强】挖宝藏
- JZOJ 3737. 【NOI2014模拟7.11】挖宝藏(treasure)
- SPFA维护dp——【NOI2014模拟7.11】挖宝藏
- ACM题目小经验
- 学习android JNI的那些事儿--------7. 在JNI中创建java类对象
- ORACLE PL/SQL编程详解之七:程序包的创建与应用
- iPhone之NSTimer
- Java输入汉字的编码问题
- 挖宝藏 treasures
- 基于HTML标签的JavaScript触发事件处理
- ORACLE PL/SQL编程之八: 把触发器说透
- SQL Server中CROSS APPLY和OUTER APPLY的应用详解
- 自定义ViewFlipperTest
- js中将字符串转换成json的三种方式
- a标签中调用javascript方法的几种方法与window.open()
- jquery load()编码问题
- 利用GSensor让屏幕实现360度旋转