2018-2019 ACM-ICPC, Asia Nakhon Pathom Regional Contest E How Many Groups

7 篇文章 0 订阅

How Many Groups

You are given an array of n integers. Define a binary relation ~ on the elements of this array
so that x ~ y if and only if |x – y| is less than or equal to 2. Let ~* be the transitive closure of
~. So x ~* y if and only if there is a sequence y_1, y_2, …, y_k = y with x ~ y_1 ~ y_2 ~ …~ y_k. We say two numbers are in the same group if they are in the same ~* equivalence class.For example consider this array: [2, 1, 7, 4, 3, 8, 9, 12, 13, 20]
This array has 4 groups:
[2,1,4,3]
[7,8,9]
[12, 13]
[20]
Your target is to transform the array so that the size of the largest group is maximized. To transform the array, you can make at most two moves. In each move, you can select an index and add or subtract 1 to/from the number at that index. It’s not allowed to select the same index twice.In the example above, you can transform the array into [2, 1, 7, 5, 3, 8, 9, 11, 13, 20] by adding 1 to the 4th index and subtracting 1 from the 8th index. Now the groups are:
[1, 2, 3, 5, 7, 8, 9, 11, 13, 20]
[20]
Size of the largest group is now 9.Find the largest possible group size obtainable by transformation and print it.
Input:
The first line contains T (1 <= T <= 13000), denoting the number of test cases. The first line of each test case contains an integer n (1 <= n <= 100) denoting the size of the array. The second line contains n integers denoting the elements of the array. Each element will be between 1 and 200.The input file is big, fast I/O is recommended.

Output:
For each test case, print the case number and the size of the largest possible group after transformation.

Input Output
5
10
2 1 7 4 3 8 9 12 13 20
3
1 2 3
4
1 2 7 8
3
10 30 20
2
5 5

Output
Case 1: 9
Case 2: 3
Case 3: 2
Case 4: 1
Case 5: 2

题意

给你一个数组。
题目定义一个关系。两个数a,b当且仅当a与b相差不超过2时,a,b 在一个分组中,让你求出一个最大的分组,输出元素个数。可以对任一位置的数进行加一或者减一 一次。不能连续对同一个数操作两次

思路

dp,先对数组进行排序,然后,dp 数组为dp[i][j],意为:以i为最后一个数的时候经过j次变化得到的最大的答案。这个变化次数不是说一共的变化次数,而是说:i 由上一个数k转移过来,i,k 一共的变化次数,显然最多一共能变化2次。那么转移方程就可以写了。
遍历数组的每一个数,显然这个数可以变成三个数(+1,0,-1)其中(+1,-1)都是变化一次的,0是不变的。然后转移。

参考自:https://blog.csdn.net/qq_40655981/article/details/89814073

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
#define maxn 209
int dp[maxn][3],a[maxn];

int main(){
    int i, j, n, m, T;
    scanf("%d",&T);
    int cas = 0;
    while(T--){
        scanf("%d",&n);
        int mm = 0;
        for(i = 1; i <= n; i++){
            scanf("%d",&a[i]);
            mm = max(a[i], mm);
        }
        sort(a+1,a+1+n);
        for(i = 0; i <= mm+1; i++)
            for(j = 2; j >= 0; j--) dp[i][j] = 0;
        for(i = 1; i <= n; i++){
            int x = a[i];
            for(j = 2; j >= 1; j--) dp[x+1][j] = max({dp[x][j-1],dp[x-1][j-1],dp[x+1][j-1]})+1;
            for(j = 2; j >= 0; j--) dp[x][j] = max({dp[x][j],dp[x-1][j],x>=2?dp[x-2][j]:0})+1;
            for(j = 2; j >= 1; j--) dp[x-1][j] = max({dp[x-1][j-1],x>=2?dp[x-2][j-1]:0,x>=3?dp[x-3][j-1]:0})+1;
        }
        int ans = 0;
        for(i = 1; i <= mm+1; i++)
            for(j = 2; j>=0; j--)
                ans = max(dp[i][j],ans);
        printf("Case %d: ",++cas);
        printf("%d\n",ans);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值