P5019 [NOIP2018 提高组] 铺设道路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
例如一个序列4 3 2 1 5 4 5
由贪心可知必然是一次选择的区间越大越好,所以每次处理一个不包括0的不上升区间即可,因为对一个不上升区间来说,要使其全部为0最多需要操作max(l-r)次,因为比区间最大值小的数消去相当于是免费的。所以统计不上升区间的最大值即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(j,b,e) for(int j=(b);j<=(e);j++)
#define drep(j,e,b) for(int j=(e);j>=(b);j--)
const int N = 1e5 + 10;
int n, m, q, k;
signed main() {
#ifndef ONLINE_JUDGE
//freopen("out.txt", "w", stdout);
#endif
ios::sync_with_stdio(0); cout.tie(0);
int n;
cin >> n;
vector<int>arr(N);
int mx = INT_MIN;
int ans = 0;
rep(j, 1, n) {
int t;
cin >> arr[j];
if (arr[j] > arr[j - 1])ans += (arr[j] - arr[j - 1]);//当后一个数严格大于前一个数说明进入下一个不上升区间
}
cout << ans;
}
CF1711B Party - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
如果当作图论来看就是,减去给定图的一些节点使剩下的边数为偶数时最小消耗。
如果边数本身就是偶数时,就不需要减去了,最小消耗为0.
如果边数为奇数时,就要考虑减去奇数条边,且顶点消耗最小。对这种情况由两种方案,
1.删去度为奇数的顶点,图的边自然减少奇数条
2.删去一条边,至多两个顶点,再多删去边由贪心可知必然劣于只删去一条边。
1很好理解,因为是无向图,一个度为一条边。
2比较困难,我们要删去一条边则需要保证剩下的顶点构成的边数要为偶数,那么删去这条边的两个顶点的度之和必须为偶数,因为这两个顶点有一条公共边,只有这样删去这两个顶点后总边数减少了(n+m)-1,当度之和(n+m)为偶数时,才会减少奇数条边。
#include<bits/stdc++.h>
using namespace std;
#pragma warning(disable:4996);
#define int long long
#define rep(j,b,e) for(int j=(b);j<=(e);j++)
#define drep(j,e,b) for(int j=(e);j>=(b);j--)
const int N = 5e5 + 10;
int T = 1;
int n, m, q, k;
using edg = pair<int, int>;
edg tem[N];
vector<int>gra[N];
signed main() {
#ifndef ONLINE_JUDGE
freopen("out.txt", "w", stdout);
#endif
ios::sync_with_stdio(0); cout.tie(0);
cin >> T;
while (T--) {
cin >> n >> k;
vector<int>arr(1);
rep(j, 1, n) {
int t;
cin >> t;
arr.push_back(t);
gra[j].clear();
}
int ans = INT_MAX;
rep(j, 1, k) {
int a, b;
cin >> a >> b;
tem[j] = { a,b };
gra[a].push_back(b);
gra[b].push_back(a);
}
rep(j, 1, n) {
if (gra[j].size() % 2)
ans = min(ans, arr[j]);
}
rep(j, 1, k) {
auto [a, b] = tem[j];
if ((gra[a].size() + gra[b].size()) % 2 == 0)
ans = min(ans, arr[a] + arr[b]);
}
if (k % 2 == 0)
cout << 0 << " \n";
else
cout << ans << endl;
}
}
3 1025. 除数博弈 - 力扣(LeetCode)
如果n为奇数,每次只能选择减去一个奇数,因为奇数的因数也为奇数,此时n变为偶数
如果n为偶数,那么可以选择减去偶数或者1.
当玩家遇到1,游戏结束,该玩家失败。
也就是说,当碰到偶数的情况,玩家可以选择让这个数变成奇数或者偶数,所以如果开局就是偶数,那么我们只需要每次将得到的数改为奇数,对方只能将这个数改为偶数,所以我们每次得到得到数都会是偶数,直到遇到2,使对方遇到1游戏胜利。所以只有开局是偶数则赢
class Solution:
def divisorGame(self, n: int) -> bool:
if n%2==0:
return True
return False
4.292. Nim 游戏 - 力扣(LeetCode)![](https://i-blog.csdnimg.cn/blog_migrate/2c616036749761da373ea8faee253953.png)
可知每个人最少都必须拿走1块石头,剩余石头少于等于3时胜利。所以当当前石头为4时该玩家必定失败。所以如果当对方石头数为4时才能获胜。所以必须初始石头必须不是4的倍数时才能获胜。
如果当对方石头数是4的倍数的时候,对方拿掉k个石头,我们可以拿掉4-k个石头保证剩下的石头仍然是4的倍数。同理,如果初始石头数是4的倍数,我们拿了k,对方可以拿4-k,此时我们的石头数永远是4的倍数直到4.我们必输。
所以初始石头数不是4的倍数我们才能赢