当前位置: 首页 > news >正文

[Gym-102091E] How Many Groups

/*
先将a数组从小到大排序
dp[i][j][k]表示到以第i个数为结尾的,且第i个数改了j次,第i个数改动值为k-1的集合最大值
ans是dp过程中的最大集合大小 
状态转移:
首先是到i改动为0次的情况:
    如果a[i]-a[i-1]<=2,dp[i][0][1]=dp[i-1][0][1]+1
    否则dp[i][0][1]=1
然后是j:1->2
        k:0->2
            先给定初始状态值 dp[i][j][k]=1 
             然后是枚举i-1的所有修改状态l:0->2
                 ai是a[i]修改后的值,aj是a[i-1]修改后的值
                这里的状态转移分两种,
                    一种是第i个数不修改,dp[i][j][1]直接由dp[i-1][j][l]转移得到
                     二种是第i个数修改,dp[i][j][0|2]有dp[i-1][j-1][l]转移得到 
dp过程中用不断更新ans
注意要使冗余状态不会对结果产生影响:冗余状态的初始值必须为0,这样从冗余态推导到可行态才会变成1
注意冗余态不要被赋初值为1即可
所以一开始不可以将dp数组初始化为0 
     
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 105

int n,a[maxn],dp[maxn][3][3];

int main(){
    int t;
    cin>>t;
    for(int tt=1;tt<=t;tt++){
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        sort(a+1,a+1+n);
        int ans=1;
        dp[1][0][1]=dp[1][1][0]=dp[1][1][2]=1;
        /*for(int i=2;i<=n;i++)
            for(int j=0;j<=2;j++)
                for(int k=0;k<=2;k++)
                    dp[i][j][k]=1;
        */        
        for(int i=2;i<=n;i++){
            for(int j=0;j<=2;j++){
                if(j==0){//到i一次也没有改的情况 
                    if(a[i]-a[i-1]<=2)
                        dp[i][0][1]=dp[i-1][0][1]+1; 
                    else dp[i][0][1]=1;
                    continue; 
                }
                //剩下的是有改动的情况 
                for(int k=0;k<=2;k++){
                    dp[i][j][k]=1;
                    for(int l=0;l<=2;l++){
                        int ai=a[i]-k+1,aj=a[i-1]-l+1;//两个数改动后的值
                        //不改动a[i]的情况
                        if(k==1){//这里不会出现冗余态:转移必定合法 
                            if(a[i]-aj<=2)
                                dp[i][j][1]=max(dp[i][j][1],dp[i-1][j][l]+1);//注意:如果从不存在的状态推过来,就是0+1的形式 
                            continue;
                        }
                        //改动a[i]的情况:这里会出现冗余态,dp[i-1][0][0|2]的状态是不存在的 
                        if(ai-aj<=2)
                            dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][l]+1); 
                    }
                }
            }
            for(int j=0;j<=2;j++)
                for(int k=0;k<=2;k++)
                    ans=max(ans,dp[i][j][k]); 
        }
        printf("Case %d: %d\n",tt,ans);
    }    
} 

 

转载于:https://www.cnblogs.com/zsben991126/p/10503893.html

相关文章:

  • pandas之数据处理
  • windows上配置mysql主从复制
  • C/C++每日小练(七)——墓地雕塑
  • Springboot- Spring缓存抽象学习笔记
  • 讲一讲垃圾回收算法
  • virtualbox 迁移虚拟机存储位置
  • 程序员面试时用中文命名写白板代码的好处
  • 019_对 100 以内的所有正整数相加求和(1+2+3+4...+100)
  • 位运算三大算法
  • Python(86)_if语句
  • 架构小谈之美团外卖
  • 【BZOJ2870】最长道路
  • C#-设计模式-观察者模式
  • Java基础内部类、包的声名、访问修饰符、代码块整理
  • c/c++ 网络编程 read,write函数深入理解
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 【翻译】babel对TC39装饰器草案的实现
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • Effective Java 笔记(一)
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • JS专题之继承
  • Next.js之基础概念(二)
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 半理解系列--Promise的进化史
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • - 概述 - 《设计模式(极简c++版)》
  • 机器学习中为什么要做归一化normalization
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 使用 @font-face
  • 学习ES6 变量的解构赋值
  • 原生Ajax
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • $$$$GB2312-80区位编码表$$$$
  • (3)nginx 配置(nginx.conf)
  • (JS基础)String 类型
  • (第61天)多租户架构(CDB/PDB)
  • (剑指Offer)面试题34:丑数
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (转)linux 命令大全
  • (轉)JSON.stringify 语法实例讲解
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .Net6使用WebSocket与前端进行通信
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • /var/lib/dpkg/lock 锁定问题
  • @AutoConfigurationPackage的使用
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • []Telit UC864E 拨号上网
  • [AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯
  • [AIGC] 使用Curl进行网络请求的常见用法
  • [C++]模板与STL简介
  • [CF703D]Mishka and Interesting sum/[BZOJ5476]位运算
  • [CISCN2019 华东南赛区]Web11