给定一组石头,每个石头有一个正数的重量。每一轮开始的时候,选择两个石头一起碰撞,假定两个石头的重量为x,y,x<=y,碰撞结果为
1. 如果x==y,碰撞结果为两个石头消失
2. 如果x != y,碰撞结果两个石头消失,生成一个新的石头,新石头重量为y-x
最终最多剩下一个石头为结束。求解最小的剩余石头质量的可能性是多少。
第一行输入石头个数(<=100)
第二行输入石头质量,以空格分割,石头质量总和<=10000
最终的石头质量
6 2 7 4 1 8 1
1
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt(),sum=0,result=0;
int[] nums=new int[n+1];
for(int i=1;i<=n;i++) {
nums[i]=scanner.nextInt();
sum+=nums[i];
}
boolean[] dp=new boolean[sum/2+1];
dp[0]=true;
for(int i=1;i<=n;i++)
for(int j=sum/2;j>=nums[i];j--)
dp[j]|=dp[j-nums[i]];
for(int j=sum/2;j>=0;j--)
if(dp[j]) {
result=Math.abs(j-(sum-j));
break;
}
System.out.println(result);
}
} #include <iostream>
(720)#include <vector>
#include <algorithm>
using namespace std;
class Solution
{
public:
int test(int n, vector<int> weights)
{
int sum = 0;
for (int weight:weights)
{
sum+=weight;
}
int maxCapcity = sum/2;
vector<int> dp(maxCapcity+1,0);
for (int i=0;i<n;i++)
{
for (int j=maxCapcity;j>=weights[i];j--)
{
dp[j] = max(dp[j],dp[j-weights[i]]+weights[i]);
}
}
return sum - 2*dp[maxCapcity];
}
};
int main()
{
int n;
cin >> n;
vector<int> weights(n);
for (int i=0;i<n;i++)
{
cin >> weights[i];
}
int res = Solution().test(n,weights);
cout << res;
return 0;
} import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int rockNum = Integer.parseInt(sc.nextLine());
int[] rockWeights = new int[rockNum];
String[] strs = sc.nextLine().split(" ");
int sumWeight = 0;
for (int i = 0; i < rockNum; i++) {
rockWeights[i] = Integer.parseInt(strs[i]);
sumWeight += rockWeights[i];
}
int[] dp = new int[(sumWeight / 2) + 1];
for (int rockWeight : rockWeights) {
for (int i = sumWeight / 2; i >= rockWeight; i--) {
dp[i] = Math.max(dp[i], dp[i - rockWeight] + rockWeight);
}
}
System.out.println(sumWeight - 2 * dp[sumWeight / 2]);
}
}
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){
int num;
cin >> num;
int *storn = new int[num];
for(int i = 0; i < num; i++) cin >> storn[i];
int sum = 0;
for(int i = 0; i < num; i++) sum += storn[i];
int max_weight = sum / 2;
int *weight = new int[max_weight + 1];
for(int i = 0; i < num; i++){
for(int j = max_weight; j >= storn[i]; j--){
weight[j] = max(weight[j], weight[j - storn[i]] + storn[i]);
}
}
cout << sum - 2 * weight[max_weight];
return 0;
} package 快手2020校园招聘秋招笔试工程C试卷;
import java.util.Scanner;
/**
* Project: 100%
* Author : en_zhao
* Email :
* Date : 2020/8/3
*/
public class Main002 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
//每个物品的重量
int num[] = new int[n+1];
int s = 0;
//求总数
for(int i = 0;i < n;i++){
num[i] = sc.nextInt();
s += num[i];
}
//背包的重量
int W = s / 2;
//背包最优解 java默认初始化为0
int[] dp = new int[W + 1];
for(int i = 0; i < n;i++){
for(int j = W; j-num[i] >= 0 ;j--){
dp[j] = Math.max(dp[j], dp[j-num[i]]+num[i]);
}
}
System.out.println(s - dp[W] - dp[W]);
}
}
package main
import (
"fmt"
)
func main() {
var n, tmp, sum, max int
var w []int
fmt.Scan(&n)
for i := 0; i < n; i++ {
fmt.Scan(&tmp)
sum += tmp
w = append(w, tmp)
}
flag := make([]bool, sum/2+1)
flag[0] = true
for _, v := range w {
for i := sum / 2; i >= v; i-- {
flag[i] = flag[i] || flag[i-v]
}
}
for i := sum / 2; i >= 0; i-- {
if flag[i] {
fmt.Print(sum - 2*i)
break
}
}
} 我开始维护CSDN了,来点个赞呗~
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] nums = new int[n];
int sum = 0;
for (int i = 0; i < n; i++) {
nums[i] = scanner.nextInt();
sum += nums[i];
}
int[][] dp = new int[n + 1][sum / 2 + 1];
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= sum / 2; j++) {
if (j >= nums[i - 1]) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i - 1]] + nums[i - 1]);
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
System.out.print(sum - 2 * dp[n][sum / 2]);
}
} import java.util.*;
/**
* @Author:
* @Date: 2020/7/26 19:48
* <p>
* 功能描述:
*/
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
int[] stones = new int[n] ;
for(int i = 0; i < n;i++){
stones[i] = sc.nextInt();
}
int ans = lastStoneWeightII(stones);
System.out.println(ans);
}
public static int lastStoneWeightII(int[] stones) {
/*
1.换一种想法,就是将这些数字分成两拨,使得他们的和的差最小
2.因此可以简单地把所有石头看作两堆,假设总重量为 sum,
则问题转化为背包问题:如何使两堆石头总重量接近 sum / 2
3.两堆石头的价值(重量)都只能接近
*/
int len = stones.length;
/* 获取石头总重量 */
int totalStone = 0;
for (int i : stones) {
totalStone += i;
}
int maxCapacity = totalStone / 2;
/*
1.这个是0-1背包的dp定义,dp[i][w]: 前i个商品,当容量为w时,最大价值为dp[i][w]
2.对照一下此题dp数组定义,dp[i][j]: 前i个石头,当容量为j时,最大重量为dp[i][j]
*/
int[][] dp = new int[len + 1][totalStone + 1];
for (int i = 1; i < len + 1; i++) {
for (int j = 1; j < maxCapacity + 1; j++) {
if (j - stones[i - 1] < 0) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = Math.max(dp[i - 1][j - stones[i - 1]] + stones[i - 1], dp[i - 1][j]);
}
}
}
return totalStone - 2 * dp[len][maxCapacity];
}
}
//0-1背包,昨天有一个类似的三层背包 和这个非常类似 都快给我搞混了,其实挺好理解的
//菜菜
#include<vector>
using namespace std;
class Solution{
public:
int getMin(vector<int> arr){
int sum = 0;
for(int i=0;i<arr.size();i++){
sum +=arr[i];
}
int C = sum/2;
vector<vector<int>> dp(arr.size(),vector<int>(C+1,0));
for(int j=0;j<=C;j++){
dp[0][j] = arr[0] <=j?arr[0]:0;
}
for(int i=1;i<arr.size();i++){
for(int j=0;j<=C;j++){
dp[i][j] = dp[i-1][j];
if(arr[i] <= j){
dp[i][j] = max(dp[i][j],arr[i] + dp[i-1][j-arr[i]]);
}
}
}
return sum - dp[arr.size()-1][C] * 2;
}
};
int main(){
int n;
cin>>n;
vector<int> arr(n);
for(int i=0;i<n;i++){
cin>>arr[i];
}
Solution c1;
cout<<c1.getMin(arr)<<endl;
return 0;
} //dp求法
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n = 0 ;
cin>>n;
vector<int>nums;
int tmp = 0;
int sum = 0;
while(cin>>tmp)
{
nums.push_back(tmp);
sum+=tmp;
}
//dp
int C = sum/2;
vector<vector<int>>dp(n,vector<int>(C+1,0));
for(int c = 0; c<=C ; ++c)
dp[0][c] = nums[0]>c?0:nums[0];
for(int i = 1 ; i < n ; ++i)
for(int c = 0 ; c <=C ; ++c)
{
if(c>=nums[i])
dp[i][c] = max(dp[i-1][c] , nums[i] + dp[i-1][c-nums[i]]);
else
dp[i][c] = dp[i-1][c];
}
cout<<sum - dp[n-1][C] * 2;
return 0;
} #include<iostream>
(720)#include<vector>
#include<cassert>
(4983)#include<algorithm>
using namespace std;
class Solution{
private:
//物品价值列表v, 重量列表w,当前背包容量c , 当前考虑的物品索引范围[0,index],返回此时能获得的最大价值
vector<vector<int>>meno;
int maxValue_recursion(const vector<int>&v, const vector<int>&w, int c, int index)
{
//终止条件
if (c == 0 || index < 0)return 0;
//递归过程
if (meno[index][c] != -1)return meno[index][c];
int res = maxValue_recursion(v, w, c, index - 1);
if (c >= w[index])
res = max(res, v[index]+maxValue_recursion(v, w, c - w[index], index - 1));
meno[index][c] = res;
return res;
}
public:
int maxValue(const vector<int>& v, const vector<int>& w, int C)
{
assert(v.size() == w.size());
int n = v.size();
meno = vector<vector<int>>(n,vector<int>(C+1,-1));
return maxValue_recursion(v, w, C, n - 1);
}
};
int main()
{
int n = 0;
cin>>n;
vector<int>v;
int tmp = 0;
int sum = 0;
while(cin>>tmp)
{
v.push_back(tmp);
sum+=tmp;
}
Solution sl;
int res = sum - sl.maxValue(v,v,sum/2)*2;
cout<<res;
#include<iostream>
using namespace std;
const int N = 110;
const int M = 10010;
int a[N];
int f[N][M];
int main() {
int n;
scanf("%d", &n);
int sum = 0;
for (int i = 1; i <= n; i ++ ) {
scanf("%d", &a[i]);
sum += a[i];
}
int V = sum / 2;
for (int i = 1; i <= n; i ++ ) {
for (int j = 0; j <= V; j ++ ) {
f[i][j] = f[i - 1][j];
if (j >= a[i]) f[i][j] = max(f[i][j], f[i - 1][j - a[i]] + a[i]);
}
}
cout << (sum - f[n][V]) - f[n][V];
return 0;
}