Timus#1005

C++【动态规划】

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	int n;
	cin >> n;
	vector<int> dp(100000 * 20);
	vector<int> a(n);
	int ans = 0, cur = 0;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
		ans += a[i];
	}
	int sum = ans / 2;
	for (int i = 0; i < n; i++)
		for (int j = sum; j >= a[i]; j--)
			dp[j] = max(dp[j], dp[j - a[i]] + a[i]);

	cout << ans - dp[sum] * 2 << endl;
	return 0;
}

C【动态规划】

#include <stdio.h>
#include <stdlib.h>
#define MAXN 100000 * 20
int main()
{
    int n;
    scanf("%d", &n);
    int* dp = (int*)malloc(sizeof(int) * (MAXN + 1));
    int a[20];
    int sum = 0, ans = 0;
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
        ans += a[i];
    }
    sum = ans / 2;
    dp[0] = 0;
    for (int i = 0; i < n; i++)
        for (int j = sum; j >= a[i]; j--)
            dp[j] = (dp[j] > dp[j - a[i]] + a[i]) ? dp[j] : dp[j - a[i]] + a[i];
    printf("%d\n", abs(ans - 2 * dp[sum]));
    free(dp);
    return 0;
}

算法介绍:动态规划

        首先计算输入数组a的总和,并设定目标和为总和的一半。初始化动态规划数组 dp,其中 dp[j]表示当前考虑了部分元素后,能否组成一个和为 j 的子集。遍历数组 a,对每个元素尝试加入到满足条件的“堆”中(即更新 dp[j]),确保在所有可能的划分方案中找到使得两个堆的和相差最小的情况。最后输出原数组总和与目标和所能达到的最大价值的两倍之差,即两堆之差的最小值。

时间复杂度:o(n^2)

这段代码的时间复杂度主要取决于两个嵌套循环的执行次数。外层循环遍历输入数组 a 的所有元素,其时间复杂度为 O(n)。 内层循环对于数组中的每个元素,会从目标和 sum 开始一直减到当前元素为止,其时间复杂度在最坏情况下是 O(sum),因为对于较大的元素,内层循环可能接近于 sum 次迭代。由于在最坏情况下,sum 可以达到数组元素总和的一半,而数组元素总和与数组大小 n 相关,因此可以假设在极端情况下,sum 与 n 成正比,即 sum = O(n)。所以,总的复杂度是外层循环与内层循环复杂度的乘积,即 O(n * sum) ≈ O(n^2)。这意味着当输入数组规模增大时,算法所需的时间将以二次方的速度增长。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶孤程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值