AtCoder Regular Contest 096

题目链接

C - Half and Half

(水题)

题意:已知存在A,B,AB三种披萨,价格分别为a,b,c,问你最少花多少钱可以买到最少x个A披萨,y个B披萨。

题解:主要就几种情况,取个最小值就行。(注意AB披萨是一半A一半B)

代码如下:

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn = 1e5 + 500;
int main() {
	ll a, b, c, x, y;
	while (~scanf("%lld%lld%lld%lld%lld", &a, &b, &c, &x, &y)) {
		ll ans = x*a + y*b;
		ll MIN = min(x, y);
		ll MAX = max(x, y);
		ans = min(ans, 2 * MIN*c + (x - MIN)*a + (y - MIN)*b);
		ans = min(ans, 2 * MAX*c);
		cout << ans << endl;
	}
	return 0; 
}

D - Static Sushi

(贪心)

题意:已知一个环形道路,周长为c,现在告诉你你在x=0的位置,环形道路上存在n个点x[i]有能量为v[i]的食物,并且你每走一步消耗1点能量(这里自身能量可以为负),求你在这环形道路上走时,某一时刻自身拥有的最大能量是多少。

题解:因为是一个环,我们可以正向走也可以反向走,同时还可以先正向走到某个点 i 再回到x=0处然后反向走到某个大于 i的点,也可以先反向走到某个点 i 再回到x=0处然后正向走到某个小于 i 的点,在这4种情况中获得的最大能量就是答案了。 

前面2种情况直接一路扫过去就行,后面2种情况需要事先预处理出2个数组,一个是正向与反向走到 i 点能获得的最大能量  dp[0/1][i],另一个是正向和反向走到 i 点然后再回到x=0处所获得的能量g[0/1][i].

那么后面2种情况对于走到某个点能获得的最大能量就是max(g[0][i] + dp[1][i + 1] , g[1][i] + dp[0][i - 1] ) ;

具体过程看代码有注释,同时当最终答案为负数也可以选择不走)

代码如下:

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define inf 0x3f3f3f3f3f3f3f
#define ll long long
const int maxn = 1e5 + 500;
ll dp[2][maxn];//dp[0][i]表示正向走到i点获得的最大能量,dp[1][i]为反向...
ll g[2][maxn];//g[0][i]表示正向走到i点回到x=0位置所拥有的能量,g[1][i]反之...
ll x[maxn], v[maxn];
ll n, c, sum;
int main() {
	scanf("%lld%lld", &n, &c);
	for (int i = 1; i <= n; i++) scanf("%lld%lld", &x[i], &v[i]);
	for (int i = 0; i <= n + 1; i++)dp[0][i] = dp[1][i] = -inf;
	for (int i = 1; i <= n; i++) {//正向遍历
		sum += v[i];  
		dp[0][i] = max(dp[0][i - 1], sum - x[i]);
		g[0][i] = sum - 2 * x[i];
	}
	sum = 0;
	for (int i = n; i >= 1; i--) {//反向遍历
		sum += v[i];
		dp[1][i] = max(dp[1][i + 1], sum - (c - x[i]));
		g[1][i] = sum - 2 * (c - x[i]);
	}
	ll ans = max(dp[0][n], dp[1][1]);
	for (int i = 1; i <= n; i++) {
		ans = max(ans, g[0][i] + dp[1][i + 1]);
		ans = max(ans, g[1][i] + dp[0][i - 1]);
	}
	printf("%lld\n", ans > 0 ? ans : 0);//若ans<0可以选择不走
	return 0;
}



你可能感兴趣的:(日常比赛,ACM,AtCoder,Contest)