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("!!!
")
#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;
}
View Code

C

子序列和子串要分清楚。。

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!
")
#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;
        }
}
View Code

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("!!!
")
#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;
}
View Code

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("!!!
")
#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();
        }
}
View Code
原文地址:https://www.cnblogs.com/Aragaki/p/8573597.html