Codeforces 946 课程表背包DP 数位DFS构造
A
B
给你A,B 两个数 1.a=0 OR b=0 break 2.a>=2b a=a-2b 3.b>=2a b=b-2a
如果只是单纯模拟肯定会超时
只需要简化 a>=2b --> a%=2b b>=2a --> b%=2a就可以
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; get min const double eps = 1.0e-10; const double EPS = 1.0e-4; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; //const int maxn = 3e5 + 10; const int maxm = 300; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //priority_queue<int, vector<int>, less<int>> que; //next_permutation ll mod = 3e7; int main() { ll a, b; cin >> a >> b; int flag = 0; while (!flag) { ll moda = 1LL * 2 * a; ll modb = 1LL * 2 * b; if (a == 0 || b == 0) { break; } if (a >= 1LL * 2 * b) { a = a % modb; continue; } else { if (b >= 1LL * 2 * a) { b = b % moda; continue; } else { break; } } //cout << a << " " << b << endl; } cout << a << " " << b << endl; }
C
子序列和子串要分清楚。。
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; get min const double eps = 1.0e-10; const double EPS = 1.0e-4; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; //const int maxn = 3e5 + 10; const int maxm = 300; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //priority_queue<int, vector<int>, less<int>> que; //next_permutation ll mod = 3e7; int num[100005]; int zimu[30]; int len; int flag=0; void dfs(int x, int now) { if(now==26) { flag=1; return; } for (int i = x; i <= len; i++) { if (num[i] <= now) { num[i] = now; dfs(i + 1, now + 1); break; } } } int main() { for (int i = 0; i <= 25; i++) { zimu[i] = i; } string a; cin >> a; flag = 0; len = a.size(); if (len <= 25) { cout << -1 << endl; return 0; } for (int i = 0; i < len; i++) { num[i + 1] = a[i] - 'a'; } dfs(1, 0); if (flag) { for (int i = 1; i <= len; i++) { char ch = 'a'; ch += num[i]; cout << ch; } } else { cout << -1 << endl; } }
D
贪心不可做 正解是背包DP
其中dp[i][j]表示前 i 天删去 j 节课所需要的最少上课时间
dp方程是 dp[i][j+k]=min(dp[i][j+k],dp[i-1][j]+ke[k]) 其中ke[i]表示的是当天除去i节课所需要最少上课时间
ke[i]需要用前缀和来算
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; get min const double eps = 1.0e-10; const double EPS = 1.0e-4; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //priority_queue<int, vector<int>, less<int>> que; //next_permutation const int maxn = 505; int pre[maxn]; char f[maxn]; int ke[maxn]; int dp[maxn][maxn]; int main() { int n, m, K; cin >> n >> m >> K; for (int i = 1; i <= n; i++) { mem(dp[i], 0x3f3f3f3f); mem(ke, 0x3f3f3f3f); scanf("%s", f + 1); for (int j = 1; j <= m; j++) { pre[j] = pre[j - 1] + (f[j] == '1'); } if (pre[m] <= K) { ke[pre[m]] = 0; } for (int j = 1; j <= m; j++) { for (int k = j; k <= m; k++) { int len = pre[m] - pre[k] + pre[j - 1]; if (len <= K) { ke[len] = min(ke[len], k - j + 1); } } } for (int j = 0; j <= K; j++) { for (int k = 0; j + k <= K; k++) { dp[i][j + k] = min(dp[i][j + k], dp[i-1][j] + ke[k]); } } } cout << dp[n][K] << endl; }
E
给你一个数字,求一个比当前数字小的 最大的漂亮数字
(漂亮数:所以在当前数中出现的数出现的次数为偶数次)
当长度为奇数时 答案明显是len-1个9
偶数时就需要搜索 找出最后面的字典序可以比原序列小的地方
如果空格数大于当前出现次数为奇数的数的个数就输出9
因为整体是偶数个数 0-9都是构造的成双出现的 所以一定满足
如果找不到 就输出len-2个9; (小的数例如10不用特殊处理 因为题目保证答案一定存在)
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; get min const double eps = 1.0e-10; const double EPS = 1.0e-4; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //priority_queue<int, vector<int>, less<int>> que; //next_permutation const int maxn = 2e5 + 5; int cnt[maxn][10]; char f[maxn]; int n; int len; void getans() { int i, j, k; for (i = len; i >= 1; i--) { for (j = (int)(f[i] - '0') - 1; j >= (i == 1); j--) { int now = 0; for (k = 0; k <= 9; k++) { now += cnt[i - 1][k] ^ (k == j); } if (now <= len - i) { for (k = 1; k < i; k++) { cout << f[k]; } cout << j; for (k = 1; k <= len - i - now; k++) { cout << 9; } for ( k = 9; k >= 0; k--) { if (cnt[i - 1][k] ^ (k == j)) { cout << k; } } cout << endl; return ; } } } for (i = 1; i <= len - 2 + (len % 2); i++) { cout << 9; } cout << endl; } int main() { cin >> n; while (n--) { scanf("%s", f + 1); len = strlen(f + 1); for (int i = 0; i <= 9; i++) { cnt[0][i] = 0; } for (int i = 1; i <= len; i++) { int now = f[i] - '0'; for (int j = 0; j <= 9; j++) { cnt[i][j] = cnt[i - 1][j] ^ (j == now); } } getans(); } }