Codeforces 675E Trains and Statistic(DP + 贪心 + 线段树)
2016-07-15 10:10
423 查看
题目大概说有n(<=10W)个车站,每个车站i卖到车站i+1...a[i]的票,p[i][j]表示从车站i到车站j所需买的最少车票数,求所有的p[i][j](i<j)的和。
好难,不会写。。
dp[i]表示Σp[i][j](j>i)
转移是dp[i]=dp[k]+(n-i)-(a[i]-k),其中k是i能直接买到的站中能直接买到最远的站,即a[k]=max(a[i+1]...a[a[i]]),这个可以用线段树快速查询
为什么从k转移?因为i+1...a[i]中除了k外能直接买到的车站都是k的子集,贪心地选择能延伸最远的k一定是没错的。
为什么转移方程是这样?dp[i],就是表示从i出发到达各个j(j>i)城市所需最少票数和,而这(n-i)个车站,对于在a[i]范围内只要从车站i买一张车票就直达了,对于大于a[i]的需要买一张车票到车站k再转车,所以就是dp[k]+(n-i);不过在dp[k]里面重复算了,要去k+1...a[i]范围的车站,明明可以直达却先到达k再转车,这多买了一张车票,所以减去(a[i]-k)。
好难,不会写。。
dp[i]表示Σp[i][j](j>i)
转移是dp[i]=dp[k]+(n-i)-(a[i]-k),其中k是i能直接买到的站中能直接买到最远的站,即a[k]=max(a[i+1]...a[a[i]]),这个可以用线段树快速查询
为什么从k转移?因为i+1...a[i]中除了k外能直接买到的车站都是k的子集,贪心地选择能延伸最远的k一定是没错的。
为什么转移方程是这样?dp[i],就是表示从i出发到达各个j(j>i)城市所需最少票数和,而这(n-i)个车站,对于在a[i]范围内只要从车站i买一张车票就直达了,对于大于a[i]的需要买一张车票到车站k再转车,所以就是dp[k]+(n-i);不过在dp[k]里面重复算了,要去k+1...a[i]范围的车站,明明可以直达却先到达k再转车,这多买了一张车票,所以减去(a[i]-k)。
#include<cstdio> #include<cstring> using namespace std; #define MAXN 111111 struct Node{ int mmm,idx; Node():mmm(0){} }tree[MAXN<<2]; int x,y,N; void update(int i,int j,int k){ if(i==j){ tree[k].mmm=y; tree[k].idx=i; return; } int mid=i+j>>1; if(x<=mid) update(i,mid,k<<1); else update(mid+1,j,k<<1|1); if(tree[k<<1].mmm>tree[k<<1|1].mmm){ tree[k]=tree[k<<1]; }else{ tree[k]=tree[k<<1|1]; } } Node query(int i,int j,int k){ if(x<=i && j<=y){ return tree[k]; } int mid=i+j>>1; Node ret; if(x<=mid){ Node tmp=query(i,mid,k<<1); if(ret.mmm<tmp.mmm) ret=tmp; } if(y>mid){ Node tmp=query(mid+1,j,k<<1|1); if(ret.mmm<tmp.mmm) ret=tmp; } return ret; } int a[MAXN]; long long d[MAXN]; int main(){ int n; scanf("%d",&n); for(N=1; N<n; N<<=1); for(int i=1; i<n; ++i){ scanf("%d",a+i); x=i; y=a[i]; update(1,N,1); } x=n; y=n; update(1,N,1); for(int i=n-1; i>=1; --i){ x=i+1; y=a[i]; Node tmp=query(1,N,1); d[i]=d[tmp.idx]+n-i-(a[i]-tmp.idx); } long long res=0; for(int i=1; i<=n; ++i){ res+=d[i]; } printf("%lld",res); return 0; }
相关文章推荐
- SDK Failed to fetch URL http://dl.google.com/android/repository
- VC6.0 error LNK2001: unresolved external symbol _main解决办法
- hdu1022-Train Problem I
- CodeForces 567A Lineland Mail
- 2015 ACM/ICPC Asia Regional Shanghai Online
- socketpair
- 百度云+AI,人工智能走进场景应用时代
- container_of学习
- Leetcode Factorial Trailing Zeroes
- Leetcode Container With Most Water
- 崩溃定位到main方法里怎么办
- Fairpixels向初创公司开源未被采用的Logo
- 373. Find K Pairs with Smallest Sums
- 杭电 1023 Train Problem II
- UVA 573 The Snail
- MainWindows
- Numpy ConfigParser.MissingSectionHeaderError: File contains no section headers.
- Raid技术白皮书(强烈推荐)
- Email邮件头揭密
- codeforces 360 D - Remainders Game