zoukankan      html  css  js  c++  java
  • CF 1110 D. Jongmah

    D. Jongmah

    链接

    题意:

      一些数字,有两种方式组成一个三元组,[x,x,x],[x,x+1,x+2],每个数字只能用一次,求最多组成多少三元组。

    分析:

      因为每三个[x,x+1,x+2]是可以拆成[x,x,x],[x+1,x+1,x+1],[x+2,x+2,x+2]的,所以可以认为对于以x开始的[x,x+1,x+2]最多有两个。

      于是可以dp[i][x][y]表示到第i个数字,存在x个[i-1,i,i+1],y个[i,i+1,i+2],最多组成多少个三元组(这些三元组的右端点在i以内,超出i三元组有x+y个,没有记录到里面)

      然后转移的时候枚举多少个[i+1,i+2,i+3]。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 1e6 + 10;
    LL f[N][3][3], a[N];
    
    int main() {
        int n = read(), m = read();
        for (int i = 1; i <= n; ++i) a[read()] ++; 
        memset(f, -0x3f, sizeof(f));
        f[0][0][0] = 0;
        for (int i = 1; i <= m; ++i) {
            for (int x = 0; x < 3; ++x)
                for (int y = 0; y < 3; ++y) 
                    for (int z = 0; z < 3; ++z) {
                        if (a[i] < x + y + z) continue;
                        f[i][x][y] = max(f[i][x][y], f[i - 1][z][x] + (a[i] - x - y - z) / 3 + z);
                    }
        }
        cout << f[m][0][0];
        return 0;
    }
  • 相关阅读:
    linux编程:删除文件夹下的空文件
    设置vim的显示颜色
    LVM的实现流程
    LVM(逻辑卷管理器)原理
    Ext2文件的访问与日志文件系统
    Linux系统的Ext2文件系统
    linux 磁盘分区的理解
    postgresql在Linux下的安装
    内存泄漏工具VLD
    关于 正交投影 与 透视投影
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10357155.html
Copyright © 2011-2022 走看看