大佬们,这道题怎么做呀?求调
查看原帖
大佬们,这道题怎么做呀?求调
1326816
hp13307747077楼主2024/12/31 22:22

时间限制: 1000ms 空间限制: 524288kB 给定一个长度为 n 的数列 {an},和一个整数 k。每次操作,你可以在两种操作中选一种:

选择某个数 ai,将它减一。即令 ai=ai-1。

选择某两个数 ai 和 aj,将一个变为另一个。即令 ai=aj。

求最少多少次操作可以让数列的和小于等于 k。

输入格式 第一行一个整数 T,表示数据组数,

每组数据第一行两个整数 n 和 k,第二行 n 个整数 a1 到 an。

输出格式 每组数据输出一行,代表答案。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, k;
        cin >> n >> k;
        vector<int> a(n);
        for (int i = 0; i < n; i++)
        {
            cin >> a[i];
        }
        vector<vector<int>> dp(n + 1, vector<int>(k + 1, 99999999));
        dp[0][0] = 0;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 0; j <= k; j++)
            {
                dp[i][j] = min(dp[i][j], dp[i - 1][j]);
                if (j + 1 <= k)
                {
                    dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1);
                }
                for (int m = 0; m < i; m++)
                {
                    int new_sum = j + a[m] - a[i - 1];
                    if (new_sum >= 0)
                    {
                        dp[i][j] = min(dp[i][j], dp[m][new_sum]);
                    }
                }
            }
        }
        int ans = 99999999;
        for (int j = 0; j <= k; j++)
        {
            ans = min(ans, dp[n][j]);
        }
        cout << ans << endl;
    }
    return 0;
}

一直RE,求调

2024/12/31 22:22
加载中...