列表

详情


DP40. 小红取数

描述

小红拿到了一个数组,她想取一些数使得取的数之和尽可能大,但要求这个和必须是  的倍数。
你能帮帮她吗?

输入描述

第一行输入两个正整数  和 
第二行输入  个正整数 

输出描述

如果没有合法方案,输出 -1。
否则输出最大的和。

示例1

输入:

5 5
4 8 2 9 1

输出:

20

说明:

取后四个数即可

原站题解

C 解法, 执行用时: 5ms, 内存消耗: 328KB, 提交时间: 2022-07-17

#include <stdio.h>
 
long long max(long long a, long long b) {
    return a > b ? a : b;
}
 
int main() {
    int n, k;
    scanf("%d %d", &n, &k);
     
    long long a[n];
    for (int i = 0; i < n; i++) {
        scanf("%lld", &a[i]);
    }
     
    long long dp[k];
    long long ndp[k];
    dp[0] = 0;
    for (int i = 1; i < k; i++) {
        dp[i] = -100000000000009;
    }
    long long v, mod;
    for (int i = 0; i < n; i++) {
        v = a[i];
        mod = v % k;
         
        if (mod == 0) {
            for (int j = 0; j < k; j++) {
                dp[j] += v;
            }
        } else {
            for (int j = 0; j < k; j++) {
                ndp[j] = max(dp[j], ((j >= mod) ? dp[j-mod] : dp[j+k-mod]) + v);
            }
            for (int j = 0; j < k; j++) {
                dp[j] = ndp[j];
            }
        }
    }
     
    if (dp[0] > 0) {
        printf("%lld", dp[0]);
    } else {
        printf("-1");
    }
     
    return 0;
}

C 解法, 执行用时: 5ms, 内存消耗: 344KB, 提交时间: 2022-06-21

#include <stdio.h>

long long max(long long a, long long b) {
    return a > b ? a : b;
}

int main() {
    int n, k;
    scanf("%d %d", &n, &k);
    
    long long a[n];
    for (int i = 0; i < n; i++) {
        scanf("%lld", &a[i]);
    }
    
    long long dp[k];
    long long ndp[k];
    dp[0] = 0;
    for (int i = 1; i < k; i++) {
        dp[i] = -100000000000009;
    }
    long long v, mod;
    for (int i = 0; i < n; i++) {
        v = a[i];
        mod = v % k;
        
        if (mod == 0) {
            for (int j = 0; j < k; j++) {
                dp[j] += v;
            }
        } else {
            for (int j = 0; j < k; j++) {
                ndp[j] = max(dp[j], ((j >= mod) ? dp[j-mod] : dp[j+k-mod]) + v);
            }
            for (int j = 0; j < k; j++) {
                dp[j] = ndp[j];
            }
        }
    }
    
    if (dp[0] > 0) {
        printf("%lld", dp[0]);
    } else {
        printf("-1");
    }
    
    return 0;
}





C++ 解法, 执行用时: 6ms, 内存消耗: 416KB, 提交时间: 2021-11-06

#include <bits/stdc++.h>
using namespace std;
int n,k;long long a[1001];
int main(){
    cin>>n>>k;
    for(int i=0;i<n;i++)scanf("%d",a+i);
    long long dp[2][1001]={},di;
    int off[2001];for(int i=0;i<k;i++){off[i]=i;off[i+k]=i;};
    for(int i=0;i<n;i++){
        di=i%2;long long (&pre)[1001]=dp[1-di],(&cur)[1001]=dp[di];
        int*offnow=off+a[i]%k;
        for(int j=0;j<k;j++){
            int index=offnow[j];
            cur[index]=pre[index];
            if(pre[j])
                cur[index]=max(cur[index],pre[j]+a[i]);
        }
        int ind=offnow[0];
        cur[ind]=max(cur[ind],a[i]);
    }
    di=(n-1)%2;long long (&pre)[1001]=dp[1-di],(&cur)[1001]=dp[di];
    if(cur[0]==0)printf("-1");
    else printf("%lld",cur[0]);
    return 0;
}

C++ 解法, 执行用时: 6ms, 内存消耗: 428KB, 提交时间: 2022-05-08

#include <bits/stdc++.h>
using namespace std;
int n, k;
long long a[1001];
int main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++)
        scanf("%d", a + i);
    long long d[2][1001] = {}, e;
    int f[2001];
    for (int i = 0; i < k; i++) {
        f[i] = i;
        f[i + k] = i;
    };
    for (int i = 0; i < n; i++) {
        e = i % 2;
        long long (&pre)[1001] = d[1 - e], (&cur)[1001] = d[e];
        int* off = f + a[i] % k;
        for (int j = 0; j < k; j++) {
            int x = off[j];
            cur[x] = pre[x];
            if (pre[j])
                cur[x] = max(cur[x], pre[j] + a[i]);
        }
        int ind = off[0];
        cur[ind] = max(cur[ind], a[i]);
    }
    e = (n - 1) % 2;
    long long (&pre)[1001] = d[1 - e], (&cur)[1001] = d[e];
    if (cur[0] == 0)
        printf("-1");
    else
        printf("%lld", cur[0]);
    return 0;
}

C++ 解法, 执行用时: 6ms, 内存消耗: 432KB, 提交时间: 2021-12-24

#include <bits/stdc++.h>
using namespace std;
int n,k;
long long a[1001];
int main(){
    cin>>n>>k;
    for(int i=0;i<n;i++)scanf("%d",a+i);
    long long dp[2][1001]={},di;
    int off[2001];
    for(int i=0;i<k;i++){off[i]=i;off[i+k]=i;};//记录余数
    for(int i=0;i<n;i++){
        di=i%2;
        long long (&pre)[1001]=dp[1-di],(&cur)[1001]=dp[di];
        int* offnow = off + a[i] % k;
        for(int j=0;j<k;j++){
            int index=offnow[j];
            cur[index]=pre[index];
            if(pre[j])
                cur[index]=max(cur[index],pre[j]+a[i]);
        }
        int ind=offnow[0];
        cur[ind]=max(cur[ind],a[i]);
    }
    di=(n-1)%2;
    long long (&pre)[1001]=dp[1-di],(&cur)[1001]=dp[di];
    if(cur[0]==0)printf("-1");
    else printf("%lld",cur[0]);
    return 0;
}

上一题