欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 每日OJ题_牛客_DP45分割等和子集_动态规划_C++_Java

每日OJ题_牛客_DP45分割等和子集_动态规划_C++_Java

2024/10/27 12:52:58 来源:https://blog.csdn.net/GRrtx/article/details/143242585  浏览:    关键词:每日OJ题_牛客_DP45分割等和子集_动态规划_C++_Java

目录

牛客_DP45分割等和子集_动态规划

题目解析

C++代码

Java代码


牛客_DP45分割等和子集_动态规划

孩子们的游戏(圆圈中最后剩下的数)_牛客题霸_牛客网

描述:

        给定一个只包含正整数的数组 nums ,请问能否把这个数组取出若干个数使得取出的数之和和剩下的数之和相同。

数据范围: 1≤n≤500  , 数组中的元素满足 1≤numsi​≤100 

输入描述:

第一行输入一个正整数 n ,表示数组 nums 的长度。

第二行输入 n 个正整数,表示数组中的值。

输出描述:

如果满足题目条件,输出 true ,否则输出 false


题目解析

01 背包问题:原问题转换成,从 n 个数中选,总和恰好为 sum / 2,能否挑选出来。

        思路转移:从一个数组中取数字,每个数字只能取一次,问取出的数字之和与未取出的数字之和能否相等。 分析:一个数组中的所有数字分为两部分,问两部分的和能否相等,很明显,如果整个数组的和(s)是奇数,必然不能。当为偶数,则判断是否能在数组中取出一些数,使得它们的和为s/2。

        这样问题转移为:容量为sum /2的背包,nums保存多个物品的重量,每个物品仅有一个,问能否把背包装满? dp[i]表示 当容量为i时,背包能最多装多重的物品。答案就是dp[sum /2]==sum /2,当容量为sum /2时,看最大能装重量是否是sum ​​​​​​​/2? 转移:dp[j] = max(dp[j], dp[j-nums[i]]+nums[i]),当j>=nums[i]时。 先遍历物品,再遍历容量:

C++代码

#include <iostream>
#include <vector>
using namespace std;int main()
{int n = 0;cin >> n;vector<int> nums(n + 1);int sum = 0;for(int i = 1; i <= n; ++i){cin >> nums[i];sum += nums[i];}if(sum % 2 == 1){cout << "false" << endl;return 0;}sum /= 2;vector<int> dp(sum + 1); // 滚动数组优化for(int i = 1; i <= n; ++i){for(int j = sum; j >= nums[i]; --j){dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);if(dp[j] == sum){cout << "true" << endl;return 0;}}}cout << "false" << endl;return 0;
}// #include <iostream>
// #include <vector>
// using namespace std;// int main()
// {
//     int n = 0;
//     cin >> n;
//     vector<int> nums(n + 1);
//     int sum = 0;
//     for(int i = 1; i <= n; ++i)
//     {
//         cin >> nums[i];
//         sum += nums[i];
//     }
//     if(sum % 2 == 1)
//     {
//         cout << "false" << endl;
//         return 0;
//     }
//     sum /= 2;
//     vector<vector<int>> dp(n + 1, vector<int>(sum + 1));
//     for(int i = 1; i <= n; ++i)
//     {
//         for(int j = 0; j <= sum; ++j)
//         {
//             dp[i][j] = dp[i - 1][j];
//             if(j >= nums[i])
//                 dp[i][j] = max(dp[i][j], dp[i - 1][j - nums[i]] + nums[i]);
//             if(dp[i][j] == sum)
//             {
//                 cout << "true" << endl;
//                 return 0;
//             }
//         }
//     }
//     cout << "false" << endl;
//     return 0;
// }

Java代码

import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main
{public static int N = 510, M = 510 * 110 / 2;public static int n;public static int[] arr = new int[N];public static boolean[][] dp = new boolean[N][M];public static void main(String[] args) {Scanner in = new Scanner(System.in);n = in.nextInt();int sum = 0;for(int i = 1; i <= n; i++){arr[i] = in.nextInt();sum += arr[i];}if(sum % 2 == 1){System.out.println("false");}else{sum /= 2;dp[0][0] = true;for(int i = 1; i <= n; i++){for(int j = 0; j <= sum; j++){dp[i][j] = dp[i - 1][j];if(j >= arr[i]){dp[i][j] = dp[i][j] || dp[i - 1][j - arr[i]];}}}if(dp[n][sum])System.out.println("true");elseSystem.out.println("false");}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com