BZOJ 2216 Poi2011 Lightning Conductor 动态规划

题目大意:给定一个序列

看了题解才知道是决策单调性。。。 那我这个做法可以算是乱搞了? (似乎这个做法也可以拓展到所有满足决策单调性的1D1D上?)

显然我们可以做两遍,第一遍只考虑 首先根号这东西有个性质。。。的增大而减小。。(其实就是函数上凸) 这意味着什么呢?这意味着对于某对就再也没有用了。。。永世不得翻身你懂? 但是如果。。。 那么我们可以开个set维护一个单调递减的决策队列。。。 对于决策队列中的每对点 然后DP的时候枚举一路往前艹过去

感觉这个写法确实可以用于所有决策单调。。。新技能get√

;int n,a[M],_sqrt[M];int f[M],g[M];set<int> q;vector<pair<int,int> > s[M]; int Bisection(int x,int y)//二分x在什么时候被y超过{int l=y+1,r=n+1;while(r-l>1){int mid=l+r>>1;if( a[x]+sqrt(mid-x) < a[y]+sqrt(mid-y) )r=mid;elsel=mid;}return a[x]+sqrt(l-x) < a[y]+sqrt(l-y) ? l : r ;}void DP(int f[]){int i;for(i=1;i<=n;i++){if( *q.begin()!=5 )++i,–i;while( !q.empty() ){set<int>::iterator it=q.end();–it;if( a[*it]+sqrt(i-*it) < a[i] )q.erase(it);elsebreak;}if( !q.empty() ){set<int>::iterator it=q.end();–it;s[Bisection(*it,i)].push_back(make_pair(*it,i));}q.insert(i);while( !s[i].empty() ){int x=s[i].back().first,y=s[i].back().second;s[i].pop_back();if( q.find(y)==q.end() )continue;set<int>::iterator it=q.find(x);if( it==q.end() )continue;while(1){if( a[*it]+sqrt(i-*it) < a[y]+sqrt(i-y) ){if( it==q.begin() ){q.erase(it);break;}set<int>::iterator temp=it;it–;q.erase(temp);}else{s[Bisection(*it,y)].push_back(make_pair(*it,y));break;}}}set<int>::iterator it=q.begin();f[i]=max(f[i],a[*it]+_sqrt[i-*it]-a[i]);}}int main(){i,j;cin>>n;for(i=1;i<=n;i++)scanf(“%d”,&a[i]);for(i=0;i*i<=n;i++)for(j=i*i+1;j<=(i+1)*(i+1)&&j<=n;j++)_sqrt[j]=i+1;DP(f);q.clear();for(i=1;i<=n+1;i++)s[i].clear();for(i=1;i<=n>>1;i++)swap(a[i],a[n-i+1]);DP(g);for(i=1;i<=n;i++)printf(“%d\n”,max(f[i],g[n-i+1]));return 0;}

,好好的管教你自己,不要管别人。

BZOJ 2216 Poi2011 Lightning Conductor 动态规划

相关文章:

你感兴趣的文章:

标签云: