BZOJ1560: [JSOI2009]火星藏宝图
2017-03-25 12:48
232 查看
首先,对于点(x,y)左上方能对他造成贡献的同一列的两个点(x1,y),(x2,y)(x1< x2),肯定下方的点(x2,y)对他的贡献更多,因为a2+b2<=(a+b)2(a,b>0)
那么一种朴素的思路是按照点的纵坐标,横坐标排完序后,对于每个点,枚举每一列最下方的点计算对它的贡献,这样的复杂度是O(nm)(貌似可以卡过去)
正解其实就是在这样的思路下加了一个斜率优化,就不用每个点都枚举m个点
复杂度O(m^2)
(斜率方程就懒得列了,自己推一下好了……)
code:
那么一种朴素的思路是按照点的纵坐标,横坐标排完序后,对于每个点,枚举每一列最下方的点计算对它的贡献,这样的复杂度是O(nm)(貌似可以卡过去)
正解其实就是在这样的思路下加了一个斜率优化,就不用每个点都枚举m个点
复杂度O(m^2)
(斜率方程就懒得列了,自己推一下好了……)
code:
#include<set> #include<map> #include<deque> #include<queue> #include<stack> #include<cmath> #include<ctime> #include<bitset> #include<string> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<climits> #include<complex> #include<iostream> #include<algorithm> #define ll long long #define inf 1e9 using namespace std; inline int read() { char c; int x; while(!((c=getchar())>='0'&&c<='9')); x=c-'0'; while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0'; return x; } inline void up(int &x,const int &y){if(x<y)x=y;} inline void down(int &x,const int &y){if(x>y)x=y;} const int maxn = 21000; const int maxm = 1100; struct node { int x,y,tx,c; node(){} node(int _x,int _y,int _tx,int _c){x=_x;y=_y;tx=_tx;;c=_c;} }q[maxn]; int head,tail; inline int multi(node x,node y,node c) { x.x-=c.x; x.y-=c.y; y.x-=c.x; y.y-=c.y; return x.x*y.y-x.y*y.x; } inline bool judge(node x,node y,double k){return double(y.y-x.y)/(double)(y.x-x.x)<k;} int a[maxm][maxm],f[maxm][maxm]; inline int cal(int x1,int x2,int y1,int y2){return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);} int ny[maxm]; int n,m; int main() { n=read(); m=read(); for(int i=1;i<=n;i++) { int x=read(),y=read(),c=read(); a[x][y]=c; } for(int x=1;x<=m;x++) { head=1,tail=0; int las=0; for(int y=1;y<=m;y++) { while(head+1<=tail&&!judge(q[head],q[head+1],-2.0*y)) head++; if(a[x][y]) { f[x][y]=-inf; if(las) f[x][y]=f[x][las]-cal(x,x,y,las); if(ny[y]) up(f[x][y],f[ny[y]][y]-cal(x,ny[y],y,y)); int nx=q[head].tx; if(head<=tail) up(f[x][y],q[head].c-cal(nx,x,q[head].x,y)); if(f[x][y]==-inf) f[x][y]=0; f[x][y]+=a[x][y]; ny[y]=x; } if(ny[y]) { int nx=ny[y]; node tmp=node(y,f[nx][y]-nx*nx+2*nx*x-y*y,nx,f[nx][y]); while(head+1<=tail&&multi(q[tail],tmp,q[tail-1])>=0) tail--; q[++tail]=tmp; } } } printf("%d\n",f[m][m]); return 0; }
相关文章推荐
- bzoj1560: [JSOI2009]火星藏宝图
- bzoj1560 [JSOI2009]火星藏宝图
- BZOJ 1560 [JSOI2009] 火星藏宝图
- bzoj 1560 [JSOI2009]火星藏宝图(DP)
- bzoj 1560 [JSOI2009]火星藏宝图(DP)
- 【BZOJ1560】[JSOI2009]火星藏宝图【DP】
- [BZOJ]1560: [JSOI2009]火星藏宝图 DP
- bzoj1560 [JSOI2009]火星藏宝图(dp+贪心)
- bzoj1560:[JSOI2009]火星藏宝图(斜率优化)
- 1560: [JSOI2009]火星藏宝图
- bzoj 1560 [JSOI2009]火星藏宝图
- 【bzoj1560】【jsoi2009】【火星藏宝图】【dp】
- 【BZOJ1560】【JSOI2009】火星藏宝图 [DP]
- BZOJ 1560 JSOI2009 火星藏宝图 动态规划
- 1560: [JSOI2009]火星藏宝图
- 【BZOJ1560】【JSOI2009】火星藏宝图 动规
- 【JSOI2009】bzoj1449 球队收益
- BZOJ 2257 [Jsoi2009] 瓶子和燃料
- BZOJ1443: [JSOI2009]游戏Game
- BZOJ 2257: [Jsoi2009]瓶子和燃料 裴蜀定理