1005. Stone Pile 背包问题 动态规划


You have a number of stones with known weights w1, …, wn. Write a program that will rearrange the stones into two piles such that weight difference between the piles is minimal.

Input

Input contains the number of stones n (1 ≤ n ≤ 20) and weights of the stones w1, …, wn (integers, 1 ≤ wi ≤ 100000) delimited by white spaces.

Output

Your program should output a number representing the minimal possible weight difference between stone piles.

Sample

inputoutput
5
5 8 13 27 14
3


这是一个背包问题,发现背包问题自己已经忘记的差不多了,所以决定重新弄清楚。

有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。
求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
基础的是01背包问题,特点是每种物品仅有一件,可以选择放或不放。
f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大值。
f[i][v] = max{f[i-1][v],f[i-1][v-w[i]]+v[i]}
压缩为f[v] = max{f[v],f[v-w[i]]+v[i]}
将问题分解为“前i件物品放入容量为v的背包中”这个子问题,如果只考虑第i件物品放入问题,那么就
转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么文件转化为“前i-1件物品放入容量为
v的背包中”,价值为f[i-1][v];如果放第i件物品,问题就转化为“前i-1件物品放入剩下的容量为
v-w[i]的背包中”,此时能获得的最大价值就是f [i-1][v-w[i]]再加上通过放入第i件物品获得的价值v[i].


#include<iostream>
using namespace std;
#define  V 1500
unsigned int f[10][V];//全局变量,自动初始化为0
unsigned int weight[10];
unsigned int value[10];
#define  max(x,y)   (x)>(y)?(x):(y)
int main()
{
    
    int N,M;
    cin>>N;//物品个数
    cin>>M;//背包容量
    for (int i=1;i<=N; i++)
    {
        cin>>weight[i]>>value[i];
    }
    for (int i=1; i<=N; i++){
        for (int j=1; j<=M; j++)
        {
            if (weight[i]<=j)
            {
                f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]]+value[i]);
            }
            else
                f[i][j]=f[i-1][j];
        }
    }
    cout<<f[N][M]<<endl;//输出最优解
}
上面计算f[i][j]可以看出,在计算f[i][j]时只使用了f[i-1][0……j],没有使用其他子问题,因此在存储子问题的解时,
只存储f[i-1]子问题的解即可。这样可以用两个一维数组解决,一个存储子问题,一个存储正在解决的子问题.
f[j]=max(f[j],f[j-weight[i]]+value[i])

#include<iostream>

using namespacestd;

#define  V 1500

unsigned int f[V];//全局变量,自动初始化为0

unsigned int weight[10];

unsigned int value[10];

#define  max(x,y)   (x)>(y)?(x):(y)

int main()

{

    

    int N,M;

    cin>>N;//物品个数

    cin>>M;//背包容量

    for (int i=1;i<=N; i++)

    {

        cin>>weight[i]>>value[i];

    }

    for (int i=1; i<=N; i++){

        for (int j=M; j>=weight[i]; j--)

        {

            f[j]=max(f[j],f[j-weight[i]]+value[i]);

        }

    }

    

    cout<<f[M]<<endl;//输出最优解

}

而这个问题可以将M设置为total/2,即可。

#include<iostream>

#include <math.h>

using namespacestd;

#define  V 2500000

unsigned int f[V];//全局变量,自动初始化为0

unsigned int weight[22];

#define  max(x,y)   (x)>(y)?(x):(y)

int main()

{

    

    int N,M;

    cin>>N;//物品个数

    int total =0;

    for (int i=1;i<=N; i++)

    {

        cin>>weight[i];

        total = weight[i] + total;

    }

    M = total/2;

    for (int i=1; i<=N; i++){

        for (int j=M; j>=weight[i]; j--)

        {

            f[j]=max(f[j],f[j-weight[i]]+weight[i]);

        }

    }

    int temp = (total-f[M])-f[M];

    cout<<abs(temp)<<endl;//输出最优解

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我理解您的问题是如何将一个包含多个数组的字典转换为 DataFrame。 您可以使用 pandas 库中的 DataFrame 函数来实现此操作。具体步骤如下: 1. 导入 pandas 库:`import pandas as pd` 2. 创建一个空的 DataFrame:`df = pd.DataFrame()` 3. 遍历字典中的每个键值对,并将它们添加到 DataFrame 中: ```python for key, value in my_dict.items(): # 将每个数组转换为 DataFrame,然后将它们合并成一个 DataFrame df_temp = pd.DataFrame(value, columns=['col1', 'col2']) # 在 DataFrame 中添加一个新的列,用字典的键作为名称 df_temp['key'] = key # 将 DataFrame 追加到主 DataFrame 中 df = df.append(df_temp, ignore_index=True) ``` 根据您提供的字典,以下是完整的代码示例和输出: ```python # 导入 pandas 库 import pandas as pd # 定义字典 my_dict = {'pile0': array([[283, 77.5], [290.5, 79.6], [277.6, 76.1], [285, 78.1], [277.5, 76], [269.5, 73.8], [290.5, 79.6], [235.8, 64.6], [267, 73.2], [291.5, 79.9]], dtype=object), 'pile1': array([[304.5, 83.4], [301.8, 82.7]], dtype=object)} # 创建空的 DataFrame df = pd.DataFrame() # 遍历字典并将值添加到 DataFrame 中 for key, value in my_dict.items(): # 将每个数组转换为 DataFrame,然后将它们合并成一个 DataFrame df_temp = pd.DataFrame(value, columns=['col1', 'col2']) # 在 DataFrame 中添加一个新的列,用字典的键作为名称 df_temp['key'] = key # 将 DataFrame 追加到主 DataFrame 中 df = df.append(df_temp, ignore_index=True) # 输出 DataFrame print(df) ``` 输出: ``` col1 col2 key 0 283.0 77.5 pile0 1 290.5 79.6 pile0 2 277.6 76.1 pile0 3 285.0 78.1 pile0 4 277.5 76.0 pile0 5 269.5 73.8 pile0 6 290.5 79.6 pile0 7 235.8 64.6 pile0 8 267.0 73.2 pile0 9 291.5 79.9 pile0 10 304.5 83.4 pile1 11 301.8 82.7 pile1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值