zoukankan      html  css  js  c++  java
  • dp 20190618

    C. Party Lemonade

    这个题目是贪心,开始我以为是背包,不过也不太好背包,因为这个L都已经是1e9了。

    这个题目怎么贪心呢?它是因为这里有一个二倍的关系,所以说val[i]=val[i-1]*2

    所以利用这个关系,我们可以求出每一个体积的最小的花费。

    这个处理完之后,我们就可以开始处理题目中的L了。

    这个L,从高位开始枚举,先求出L个中最多并且要小于等于这个最大值可以用的这个物品的数量,然后如果是小于,那么再多选一次,这样肯定会超出体积,

    不过这样就保证了大于等于L。

    对于下面一个L取完膜之后继续这样处理,最后求出最小值。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 10;
    ll val[50];
    
    int main()
    {
        int n;
        ll L;
        scanf("%d%I64d", &n, &L);
        for (int i = 1; i <= n; i++) scanf("%I64d", &val[i]);
        for (int i = 2; i <= n; i++) val[i] = min(val[i], val[i - 1] * 2);
        ll ans = inf64, sum = 0;
        for(int i=n;i>=1;i--)
        {
            ll len = 1 << (i - 1);
            ll num = L / len;
            sum += num * val[i];
            L %= len;
            ans = min(ans, sum + (L > 0)*val[i]);
        }
        printf("%I64d
    ", ans);
        return 0;
    }
    C

    B. Dima and a Bad XOR

    这个题目其实比较简单,就是找规律,如果找出来了,就很简单了。

    首先我发现如果每一行有两个不同的数,那么肯定是可以的,然后lj发现如果最后一行有两个不相同的数,那么肯定也是可以的,最后就可以推出来

    如果任意一行有两个数不同,那么肯定也是可以的。

    这样子就很简单了。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 10;
    int mp[550][550];
    
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        int flag = 0, mark = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                scanf("%d", &mp[i][j]);
                if (!flag&&j > 1 && mp[i][j] != mp[i][1]) {
                    flag = i;
                    mark = j;
                }
            }
        }
        if (!flag)
        {
            int ans = 0;
            for (int i = 1; i <= n; i++) ans ^= mp[i][1];
            if (ans == 0) printf("NIE
    ");
            else
            {
                printf("TAK
    ");
                for (int i = 1; i < n; i++) printf("1 ");
                printf("1
    ");
            }
        }
        else
        {
            printf("TAK
    ");
            int ans = 0;
            for (int i = 1; i <= n; i++) ans ^= mp[i][1];
            if(ans)
            {
                for (int i = 1; i < n; i++) printf("1 ");
                printf("1
    ");
            }
            else
            {
                for(int i=1;i<=n;i++)
                {
                    if (i == flag) printf("%d ", mark);
                    else printf("1 ");
                }
                printf("
    ");
            }
        }
        return 0;
    }
    B

    J 牛客假日团队赛1 分组

    这个题目其实很不好想,这个是lj一步步引导我才写出来的,

    首先这个题目每一个位置可以往后面推出 1~k 所以算一下复杂度是1e7

    dp[i]表示以 i 为最后一个值,从 1~i 的最大的分完组之后的和。

    所以这个就有刷表法和填表法,

    就是从这个状态往后推和每一个状态从前面推过来,第一个很好写,后面那个比较难。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e4 + 10;
    int dp[maxn];
    int a[maxn];
     
    int main()
    {
        int n, k;
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        for(int i=0;i<=n;i++)
        {
            int mxx = 0;
            for(int j=1;j<=k;j++)
            {
                if (i + j > n) break;
                mxx = max(mxx, a[i + j]);
                dp[i + j] = max(dp[i + j], dp[i] + j * mxx);
                //printf("i=%d j=%d dp[%d]=%d
    ", i, j, i + j, dp[i + j]);
            }
        }
        printf("%d
    ", dp[n]);
        return 0;
    }
    1
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e4 + 10;
    int dp[maxn];
    int a[maxn];
     
    int main()
    {
        int n, k;
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        for(int i=1;i<=n;i++)
        {
            int mxx = 0;
            for(int j=0;j<k;j++)
            {
                if (i < j + 1) break;
                mxx = max(mxx, a[i - j]);
                dp[i] = max(dp[i],dp[i - j - 1] + mxx * (j + 1));
                // printf("i=%d j=%d dp[%d]=%d dp[%d]=%d
    ", i, j, i, dp[i],i-j,dp[i-j]);
                // printf("mxx=%d
    ", mxx);
            }
        }
        printf("%d
    ", dp[n]);
        return 0;
    }
    2
  • 相关阅读:
    谷歌浏览器解决跨域
    vue 解决跨域问题
    nth-of-type & nth-child 的区别
    uniapp 小程序 获取位置信息
    笔记本使用命令创建wifi
    express每次修改后重新启动
    express 一个js文件中写多个路由 然后使用
    小程序分享到朋友圈
    小程序分享给朋友
    小程序客服功能实现
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11043552.html
Copyright © 2011-2022 走看看