Codeforces Beta Round #61 (Div. 2) E. Petya and Post
2014-09-01 15:53
330 查看
考虑最暴力的方法 ,就是从每点去模拟,用一个变量cur记录当前油箱的油量,一旦发现某个时刻cur小于0,则是无解。但这个做法一定是不可以了,会超时。
不过我们可以从暴力做法里面获得一些启发。考虑cur在变化过程中的最小值min_cur,明显有min_cur<=0,记dp[i]为从i点出发,想要转一圈回来,在i点未加油时最少需要的油量是多少。显然dp[i]=min_cur.
题目还有一个重要的信息,对a求和等于对b求和。那么在暴力求法中,cur最后一定归0(中途可能是负的),那么也就是说,在终点前一个点加油后油量一定是正的。那么dp[i]就有另一个含义从i点出发沿i,i+1,i+2,...,走到i-1所需的最小油量,因为能走到i-1,就一定能到i。
那么
dp[i]=max(b[i]-a[i],dp[i+1]-(a[i]-b[i]))=max(b[i]-a[i],dp[i+1]-a[i]+b[i])=dp[i+1]-a[i]+b[i] (dp[i+1]>=0)
b[i]-a[i]表示能从i到i+1
dp[i+1]-a[i]+b[i]表示先从i到i+1,在从i+1到i(dp[i+1]取第二个含义),合起来就是从i到i(dp[i]取第一个含义)
这样从任意一个点暴力求一次dp[i],再O(n)递推其他点的dp值即可。注意题目中有两个方向,那么做两次即可。
不过我们可以从暴力做法里面获得一些启发。考虑cur在变化过程中的最小值min_cur,明显有min_cur<=0,记dp[i]为从i点出发,想要转一圈回来,在i点未加油时最少需要的油量是多少。显然dp[i]=min_cur.
题目还有一个重要的信息,对a求和等于对b求和。那么在暴力求法中,cur最后一定归0(中途可能是负的),那么也就是说,在终点前一个点加油后油量一定是正的。那么dp[i]就有另一个含义从i点出发沿i,i+1,i+2,...,走到i-1所需的最小油量,因为能走到i-1,就一定能到i。
那么
dp[i]=max(b[i]-a[i],dp[i+1]-(a[i]-b[i]))=max(b[i]-a[i],dp[i+1]-a[i]+b[i])=dp[i+1]-a[i]+b[i] (dp[i+1]>=0)
b[i]-a[i]表示能从i到i+1
dp[i+1]-a[i]+b[i]表示先从i到i+1,在从i+1到i(dp[i+1]取第二个含义),合起来就是从i到i(dp[i]取第一个含义)
这样从任意一个点暴力求一次dp[i],再O(n)递推其他点的dp值即可。注意题目中有两个方向,那么做两次即可。
#include <bits/stdc++.h> #define maxn 100009 using namespace std; bool vis[maxn]; int a[maxn],b[maxn],dp[maxn],n; int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) scanf("%d",&b[i]); int cur=0; for(int i=0;i<n;i++) { cur=cur+a[i]-b[i]; dp[0]=min(dp[0],cur); } dp[0]=-dp[0]; if(dp[0]==0) vis[0]=1; for(int i=n-1;i>0;i--) { dp[i]=dp[(i+1)%n]-(a[i]-b[i]); if(dp[i]==0) vis[i]=1; } memset(dp,0,sizeof(dp)); cur=0; for(int i=n-1;i>=0;i--) { cur=cur+a[i]-b[((i-1)%n+n)%n]; dp[n-1]=min(dp[n-1],cur); } dp[n-1]=-dp[n-1]; if(dp[n-1]==0) vis[n-1]=1; for(int i=0;i<n-1;i++) { dp[i]=dp[((i-1)%n+n)%n]-(a[i]-b[((i-1)%n+n)%n]); if(dp[i]==0) vis[i]=1; } int cnt=0; for(int i=0;i<n;i++) { if(vis[i]) cnt++; } printf("%d\n",cnt); for(int i=0;i<n;i++) { if(vis[i]) printf("%d ",i+1); } system("pause"); return 0; }
相关文章推荐
- Codeforces Round #212 (Div. 2) B. Petya and Staircases
- Codeforces Round #425 (Div. 2) B. Petya and Exam【模拟】
- Codeforces Beta Round #61 (Div. 2) B. Petya and Countryside (DP)
- Codeforces Round #425 (Div. 2) B. Petya and Exam
- Codeforces Round #212 (Div. 2) A. Two Semiknights Meet /B. Petya and Staircases
- Codeforces Beta Round #6 (Div. 2 Only) D. Lizards and Basements 2 dp
- Codeforces Round #212 (Div. 2) B. Petya and Staircases
- Codeforces Round #425 (Div. 2) B. Petya and Exam
- Codeforces Round #169 (Div. 2):E - Little Girl and Problem on Trees
- Codeforces Beta Round #80 (Div. 2 Only)
- Codeforces Round #154 (Div. 2) A. Boys and Girls
- Codeforces Round #182 (Div. 1) B. Yaroslav and Time(二分+SPFA变形)
- [Codeforces Round #154 (Div. 2)]A. Boys and Girls
- Codeforces Beta Round #35 (Div. 2) E. Parade(成段更新)
- Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings
- Codeforces Round #179 (Div. 2) C Greg and Array
- Codeforces Round #174 (Div. 2) Cows and Sequence(线段树)
- Codeforces Beta Round #69 (Div. 2 Only)——A,B,D
- Codeforces Beta Round #99 (Div. 1) C Mushroom Gnomes - 2(单点查询)
- Codeforces Round#179(Div 2)C Greg and Array