zoukankan      html  css  js  c++  java
  • Codeforces 922 思维贪心 变种背包DP 质因数质数结论

    A

    #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-8;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 3e7 + 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 = 1e9 + 7;
    int main()
    {
            int x, y;
            cin >> x >> y;
            if (x == 0 || y == 0)
            {
                    if (x == 0 && y == 1)
                    {
                            cout << "Yes" << endl;
                    }
                    else
                    {
                            cout << "No" << endl;
                    }
                    return 0;
            }
            int cur = y - 1;
            int remain = x - cur;
            if (remain % 2 == 0 && cur && remain>=0)
            {
                    cout << "Yes" << endl;
                    return 0;
            }
            cout << "No" << endl;
            return 0;
    }
    View Code

    B

    #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 turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    ll Mod = 1000000007;
    int num[10000];
    int cnt;
    bool check(int a, int b, int c)
    {
            if (a + b > c && a + c > b && b + c > a)
            {
                    return true;
            }
            return false;
    }
    int main()
    {
            int n;
            int anser = 0;
            cin >> n;
            for (int i = 1; i < n; i++)
            {
                    for (int j = i + 1; j <= n; j++)
                    {
                            int aim = (i ^ j);
                            if (aim >= j && aim <= n && check(i, j, aim))
                            {
                                    //cout << i << " " << j << " " << aim << endl;
                                    anser++;
                            }
                    }
            }
            cout << anser << endl;
            return 0;
    }
    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;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    //const int maxn = 3e5 + 10;
    const int  maxn = 100005;
    const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    const int turn2[8][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}, {1, -1}, { -1, -1}, {1, 1}, { -1, 1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    int main()
    {
            //freopen("sample.txt", "w", stdout);
            ll n, k;
            cin >> n >> k;
            if (n == 1 && k <= 2)
            {
                    cout << "Yes" << endl;
                    return 0;
            }
            if (k >= n)
            {
                    cout << "No" << endl;
            }
            else
            {
                    for (ll i = 1; i <= min(1LL * 50, k); i++)
                    {
                            if (n % i != i - 1)
                            {
                                    cout << "No" << endl;
                                    return 0;
                            }
                    }
                    cout << "Yes" << endl;
            }
            return 0;
    }
    View Code

    D

    奇葩贪心题 假设有两个字符串A B A在B前面的条件是什么?

    假设A有SHa个sh BSHb A有Sa个s BSb A有Ha个h BHb 当 SHa+SHb+Sa*Hb>SHa+SHb+Sb*Ha 时成立

    转换一下就是A的sh比例比B高的时候 A在B前面

    #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;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    //const int maxn = 3e5 + 10;
    const int  maxn = 100005;
    const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    const int turn2[8][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}, {1, -1}, { -1, -1}, {1, 1}, { -1, 1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    struct node
    {
            string str;
            double per;
    } s[100005];
    bool operator <(node a, node b)
    {
            return a.per > b.per;
    }
    ll pre[100005];
    string aim = "";
    int main()
    {
            ll anser = 0;
            //freopen("sample.txt", "w", stdout);
            int n;
            cin >> n;
            for (int i = 1; i <= n; i++)
            {
                    int now = 0;
                    cin >> s[i].str;
                    int len = s[i].str.size();
                    for (int j = 0; j < len; j++)
                    {
                            if (s[i].str[j] == 's')
                            {
                                    now++;
                            }
                    }
                    if (len - now == 0)
                    {
                            s[i].per = 1000000;
                    }
                    else
                    {
                            s[i].per = (double)now / (double)(len - now);
                    }
                    //cout << s[i].per << endl;
            }
            sort(s + 1, s + 1 + n);
            for (int i = 1; i <= n; i++)
            {
                    aim += s[i].str;
            }
            //cout << aim << endl;
            int lenth = aim.size();
            for (int i = 0; i < lenth; i++)
            {
                    if (i == 0)
                    {
                            pre[i] = (aim[i] == 's');
                    }
                    else
                    {
                            pre[i] = pre[i - 1] + (aim[i] == 's');
                    }
                    if (aim[i] == 'h')
                    {
                            anser += pre[i];
                    }
            }
            cout << anser << endl;
            return 0;
    }
    View Code

    E

    一般想到的DP思路是DP[i][j]表示前i个用了j块钱能吸引多少鸟 但是这里j太大了(于是题目就提示你C[i]的总值不超过10000)

    所以用DP[i][j]表示在前i个吸引了j个鸟最多好剩多少魔力   复杂度:   前面的复杂度是pre[i]较小的时候 后面是pre[i]较大的时候

    DP方程:

    #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;
    typedef pair<int, int> pairint;
    typedef long long ll;
    typedef unsigned long long ull;
    //const int maxn = 3e5 + 10;
    const int  maxn = 100005;
    const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    const int turn2[8][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}, {1, -1}, { -1, -1}, {1, 1}, { -1, 1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    ll n, W, B, X;
    ll c[1005];
    ll pre[1005];
    ll cost[1005];
    ll dp[1005][10005];
    int main()
    {
            //freopen("sample.txt", "w", stdout);
            // W初始值 B增加的上限 X回复的数目
            mem(dp, -1);
            cin >> n >> W >> B >> X;
            dp[0][0] = W;
            for (int i = 1; i <= n; i++)
            {
                    cin >> c[i];
                    pre[i] = pre[i - 1] + c[i];
            }
            for (int i = 1; i <= n; i++)
            {
                    cin >> cost[i];
            }
            for (ll i = 1; i <= n; i++)
            {
                    for (ll j = 0; j <= pre[i]; j++)
                    {
                            for (ll k = 0; k <= min(j, c[i]); k++)
                            {
                                    if (dp[i - 1][j - k] == -1 || 1LL * cost[i]*k > dp[i - 1][j - k])
                                    {
                                            continue;
                                    }
                                    dp[i][j] = max(dp[i][j], dp[i - 1][j - k] - 1LL * k * cost[i]);
                            }
                            if (dp[i][j] != -1)
                            {
                                    dp[i][j] = min(dp[i][j] + X, W + 1LL * j * B);
                            }
                    }
            }
            for (int i = pre[n]; i >= 0; i--)
            {
                    if (dp[n][i] >= 0)
                    {
                            cout << i << endl;
                            return 0;
                    }
            }
            return 0;
    }
    View Code

     F

    先N*lnN处理出每个数的被除数个数 然后做前缀和 如果K>dp[N] 就无解

    所以猜测 当dp[i]>=k时即有解 当数据大于10时 dp数列每两个之间相差不会超过各自之下的i/2+1~i的质数个数(为什么选i/2~i的质数是因为其sum[i]只为1 方便调整)

    所以当N>10的时候找到最小的满足dp[i]>=k的i 然后用删去其i/2+1~i之间的质数来调整 dp[i]-k

    后来知道 当N<=10的时候 也满足>10的解法  一个数N的被整除数在N^(1/3)数量级 质数则在 N/LogN数量级

    #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 turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}};
    //priority_queue<int, vector<int>, less<int>> que;
    //next_permutation
    ll Mod = 1000000007;
    vector<int> prime;
    int n;
    ll k;
    int anserten;
    ll sum[300005];
    ll dp[300005];
    int visit[300005];
    void dfs(int pos, int x)
    {
            if (pos == n + 1)
            {
                    if (anserten == 0)
                    {
                            int now = 0;
                            for (int i = 1; i <= 5; i++)
                            {
                                    if (x & (1 << i))
                                    {
                                            for (int j = i * 2; j <= 10; j += i)
                                            {
                                                    if (x & (1 << j))
                                                    {
                                                            //cout << i << " " << j << endl;
                                                            now++;
                                                    }
                                            }
                                    }
                            }
                            if (now == k)
                            {
                                    anserten = x;
                            }
                    }
                    return ;
            }
            dfs(pos + 1, x + (1 << pos));
            dfs(pos + 1, x);
    }
    priority_queue<pair<int, int> > que;
    int main()
    {
            cin >> n >> k;
            for (int i = 1; i <= n; i++)
            {
                    for (int j = i * 2; j <= n; j += i)
                    {
                            sum[j]++;
                    }
            }
            for (int i = 1; i <= n; i++)
            {
                    dp[i] = dp[i - 1] + sum[i];
            }
            if (k > dp[n])
            {
                    cout << "No" << endl;
                    return 0;
            }
            else
            {
                    cout << "Yes" << endl;
                    if (n <= 10)
                    {
                            dfs(1, 0);
                            int anser = 0;
                            for (int i = 1; i <= 10; i++)
                            {
                                    if (anserten & (1 << i))
                                    {
                                            anser++;
                                    }
                            }
                            cout << anser << endl;
                            for (int i = 1; i <= 10; i++)
                            {
                                    if (anserten & (1 << i))
                                    {
                                            cout << i << " ";
                                    }
                            }
                            cout << endl;
                    }
                    else
                    {
                            dp[n + 1] = INT_MAX;
                            int aim;
                            for (aim = 1; aim <= n; aim++)
                            {
                                    if (dp[aim] >= k && dp[aim - 1] < k)
                                    {
                                            break;
                                    }
                            }
                            int anser = aim;
                            for (int i = aim; i >= 1; i--)
                            {
                                    visit[i] = 1;
                            }
                            for (int i = aim; i >= aim / 2 + 1; i--)
                            {
                                    que.push({sum[i], i});
                            }
                            int cha = dp[aim] - k;
                            pair<int, int> cnt;
                            while (cha > 0)
                            {
                                    cnt = que.top();
                                    que.pop();
                                    if (cnt.first <= cha)
                                    {
                                            cha -= cnt.first;
                                            visit[cnt.second] = 0;
                                            anser--;
                                    }
                            }
                            cout << anser << endl;
                            for (int i = 1; i <= aim; i++)
                                    if (visit[i])
                                    {
                                            cout << i << " ";
                                    }
                            cout << endl;
                    }
            }
            return 0;
    }
    View Code
  • 相关阅读:
    多个自定义覆盖物注册点击事件,点击某个覆盖物后获得它的坐标
    C# 文件操作(全部) 追加、拷贝、删除、移动文件、创建目录 修改文件名、文件夹名
    如何添加EXEStealth 2.5x 壳
    PACS系统简易
    好用的后端模版
    E信通项目总结[转]
    平台型产品的设计思路[转]
    baidu思维脑图在线编辑器
    Web 前端攻防(2014版)-baidu ux前端研发部
    访谈标叔:给新人设计师的建议【转】
  • 原文地址:https://www.cnblogs.com/Aragaki/p/8666725.html
Copyright © 2011-2022 走看看