Codeforces Round #353 (Div. 2)E. Trains and Statistic
2016-05-18 16:51
513 查看
链接:http://codeforces.com/contest/675/problem/E
题意:给定n个火车站的信息,a[i]表示能在第i站买到去i+1~a[i]之间任意一站的票(a
因为是终点站所以只给前n-1个站的信息),设f[i][j]表示从第i个站到第j个站至少要买多少次票。求sum=f[i][j](i<j)。
分析:CF上是有题解的,不过这个题解挺简练的,需要立即其中的含义。我们设dp[i]表示从第i站到i+1~n所有站所需要的最少次购票,那么有dp[i]=dp[m]-(a[i]-m)+n-i且m是i+1~a[i]之间的数且a[m]最大,如果有多个m取是dp[i]最小的那个。这是CF官方题解给出的dp方程式。首先我们理解一下为什么是取这个m,显然出题人的意思是dp[i]是要从这个a[m]最大上面去继承答案。我们简单画一下图就能发现这样一个大小关系:i<m<a[i]<a[m]<n。这个n-i显然是表示i+1~n每个站至少买一次票,那么哪些站多买了呢?m+1~a[i]这些站,因为之前m到这些站就买了一次票,这一次再买就重复了,于是就有-(a[i]-m)。那么怎么能保证a[i]+1~n的每一站是买的最少的票呢?那么就直接继承dp[m]中最小的买票次数就行啦。
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<cstdio> #include<vector> #include<string> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=100010; const int MAX=1000000100; const int mod=100000000; const int MOD1=1000000007; const int MOD2=1000000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=998244353; const int INF=1000000010; typedef double db; typedef unsigned long long ull; int a ,f [20]; ll p ,dp ; void deal(int n) { int i,j; for (i=1;i<=n;i++) f[i][0]=a[i]; for (i=1;i<20;i++) for (j=1;j<=n;j++) if (j+(1<<i)-1<=n) f[j][i]=max(f[j][i-1],f[j+(1<<(i-1))][i-1]); else break ; } int find_mx(int l,int r) { int m=(int)log2(r-l+1); return max(f[l][m],f[r-(1<<m)+1][m]); } int main() { int i,n,mx; ll ans=0; scanf("%d", &n); for (i=1;i<n;i++) scanf("%d", &a[i]); a =n;deal(n); memset(p,-1,sizeof(p)); dp =0;p =n; for (i=n-1;i;i--) { mx=find_mx(i+1,a[i]); dp[i]=p[mx]-a[i]+n-i;ans+=dp[i]; if (p[a[i]]==-1) p[a[i]]=dp[i]+i; else p[a[i]]=min(p[a[i]],dp[i]+i); } printf("%I64d\n", ans); return 0; }
相关文章推荐
- svn cleanup failed–previous operation has not finished; run cleanup if it was interrupted
- ASM磁盘超过disk_repair_time导致磁盘状态为forcing
- ASM磁盘超过disk_repair_time导致磁盘状态为forcing
- Saiku AdminConsole
- ASM磁盘超过disk_repair_time导致磁盘状态为forcing
- copy和mutableCopy,retain
- Jmeter报告优化
- [leetcode] 336. Palindrome Pairs 解题报告
- 【转】async & await 的前世今生
- 【杂题】[POJ3222]Edge Pairing
- 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?readwrite,reado
- 主题 : clang: error: linker command failed with exit code 1 (use -v to see invocation)
- LeetCode Climbing Stairs(经典动态规划)
- Makefile 没有规则创建目标“main.o”需要的目标“main.c”
- LeetCode 217. Contains Duplicate
- DailyNote
- Creating schema using Saiku Schema Designer
- Codeforces Round #353 (Div. 2) E. Trains and Statistic(求d[i][j]的和的最小值(1<=i<=n,i+1<=j<=n))
- SendKeys.SendWait()BUG解决方法
- Cookie未设置Domain