zoukankan      html  css  js  c++  java
  • #线性dp#CF1110D Jongmah

    题目


    分析

    考虑三个 ((i,i+1,i+2)) 可以用 ((i,i,i))((i+1,i+1,i+1))((i+2,i+2,i+2)) 代替,

    所以这样的三元组本质上最多出现两次,设 (dp[n][i][j]) 表示

    (n) 个其中 (i) 个作为 ((n-1,n,n+1))(j) 个作为 ((n,n+1,n+2)) 的最多三元组个数,

    那么 (dp[n][i][j]=sum_{k=0}^2 dp[n-1][j][k]+i+lfloorfrac{a_n-i-j-k}{3} floor)

    最后答案为 (dp[n][0][0])


    代码

    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=1000011;
    int n,m,a[N],dp[3][3],f[3][3];
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline signed max(int a,int b){return a>b?a:b;}
    signed main(){
    	n=iut(); m=iut();
    	for (rr int i=1;i<=n;++i) ++a[iut()];
    	for (rr int P=1;P<=m;++P){
    		memset(f,0,sizeof(f));
    		for (rr int j=0;j<3;++j)
    		for (rr int i=0;i<3;++i)
    		for (rr int k=0;k<3;++k)
    		if (a[P]>=k+j+i)
    		    f[j][i]=max(f[j][i],dp[k][j]+i+(a[P]-k-j-i)/3);
    		memcpy(dp,f,sizeof(dp));
    	}
    	return !printf("%d",dp[0][0]);
    }
    
  • 相关阅读:
    51nod1376 最长递增子序列的数量
    51nod1201 整数划分
    51nod1202 子序列个数
    51nod 博弈论水题
    51nod1052 最大M子段和
    51nod1678 lyk与gcd
    51nod1262 扔球
    BZOJ2763, 最短路
    吃西瓜 最大子矩阵 三维的。 rqnoj93
    noip2015 信息传递 强连通块
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/15343571.html
Copyright © 2011-2022 走看看