Codeforces 1408 B. Arrays Sum

You are given a non-decreasing array of non-negative integers 𝑎1,𝑎2,…,𝑎𝑛. Also you are given a positive integer 𝑘.

You want to find 𝑚 non-decreasing arrays of non-negative integers 𝑏1,𝑏2,…,𝑏𝑚, such that:

The size of 𝑏𝑖 is equal to 𝑛 for all 1≤𝑖≤𝑚.
For all 1≤𝑗≤𝑛, 𝑎𝑗=𝑏1,𝑗+𝑏2,𝑗+…+𝑏𝑚,𝑗. In the other word, array 𝑎 is the sum of arrays 𝑏𝑖.
The number of different elements in the array 𝑏𝑖 is at most 𝑘 for all 1≤𝑖≤𝑚.
Find the minimum possible value of 𝑚, or report that there is no possible 𝑚.

Input
The first line contains one integer 𝑡 (1≤𝑡≤100): the number of test cases.

The first line of each test case contains two integers 𝑛, 𝑘 (1≤𝑛≤100, 1≤𝑘≤𝑛).

The second line contains 𝑛 integers 𝑎1,𝑎2,…,𝑎𝑛 (0≤𝑎1≤𝑎2≤…≤𝑎𝑛≤100, 𝑎𝑛>0).

Output
For each test case print a single integer: the minimum possible value of 𝑚. If there is no such 𝑚, print −1.

Example
inputCopy
6
4 1
0 0 0 1
3 1
3 3 3
11 3
0 1 2 2 3 3 3 4 4 4 4
5 3
1 2 3 4 5
9 4
2 2 3 5 7 11 13 13 17
10 7
0 1 1 2 3 3 4 5 5 6
outputCopy
-1
1
2
2
2
1
Note
In the first test case, there is no possible 𝑚, because all elements of all arrays should be equal to 0. But in this case, it is impossible to get 𝑎4=1 as the sum of zeros.

In the second test case, we can take 𝑏1=[3,3,3]. 1 is the smallest possible value of 𝑚.

In the third test case, we can take 𝑏1=[0,1,1,1,2,2,2,2,2,2,2] and 𝑏2=[0,0,1,1,1,1,1,2,2,2,2]. It’s easy to see, that 𝑎𝑖=𝑏1,𝑖+𝑏2,𝑖 for all 𝑖 and the number of different elements in 𝑏1 and in 𝑏2 is equal to 3 (so it is at most 3). It can be proven that 2 is the smallest possible value of 𝑚.

题意:
要你构造m个b数组,使得每个b数组长度为n,且不同的数字最多为k。
使得 a [ i ] = ∑ b [ j ] [ i ] a[i]=∑b[j][i] a[i]=b[j][i], b [ j ] [ i ] b[j][i] b[j][i]代表第 j j j b b b数组的第 i i i个数字。

思路:
赛中的时候读错题了,以为是所有b数组最多只有k个不同的数。
但实际上是对于每个b数组有k个不同数。
那么第一个b数组可以消灭掉前k个数,之后每个b数组依次消灭后面(k-1)个数(最前面是0)。
同时特判一下无解的情况即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;

const int maxn = 1e5 + 7;

int vis[105];

int main() {
    int T;scanf("%d",&T);
    while(T--) {
        int n,k;scanf("%d%d",&n,&k);
        int cnt = 0;
        memset(vis,0,sizeof(vis));
        for(int i = 1;i <= n;i++) {
            int x;scanf("%d",&x);
            if(!vis[x]) {
                vis[x] = 1;
                cnt++;
            }
        }
        if(k == 1 && cnt != 1) printf("-1\n");
        else if(k == 1) printf("1\n");
        else if(cnt <= k) printf("1\n");
        else printf("%d\n",1 + (cnt - k + k - 2) / (k - 1));
    }
    return 0;
}

赛中的递归写法

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

int vis[1005];
int dfs(vector<int>vec,int k) {
    int n = vec.size();
    int flag = 1;
    for(int i = 0;i < vec.size();i++) {
        if(vec[i] != 0) flag = 0;
    }
    if(flag) return 0;
    
    int res = 0;
    int pre = vec[0];
    vec[0] = 0;
    int num = k - 1;
    for(int i = 1;i < n;i++) {
        if(vec[i] != vec[i - 1]) {
            if(num) {
                num--;
                pre = vec[i];
            }
        }
        vec[i] -= pre;
    }
    
    return dfs(vec,k) + 1;
}

int main() {
    int T;scanf("%d",&T);
    while(T--) {
        int n,k;scanf("%d%d",&n,&k);
        memset(vis,0,sizeof(vis));
        int cnt = 0;
        vector<int>vec;
        for(int i = 1;i <= n;i++) {
            int x;scanf("%d",&x);
            if(!vis[x]) {
                vis[x]++;
                vec.push_back(x);
                cnt++;
            }
        }
        if(k == 1 && cnt > 1) {
            printf("-1\n");
        } else {
            int res = dfs(vec,k);
            printf("%d\n",res);
        }
    }
    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值