202209-2 何以包邮?

题意:输入第一行为n,x两个正整数。分别表示n本书和可以包邮的价格下限x。随后n行表示第i本书的价格。

现在要求出在所有大于x的价格中,最小的那个。这里的价格是指任意买m( m <= n)本书的总价格。

思路:动态规划,0-1背包问题。

0-1背包问题是说:有n件物品,每件物品重量为w[i],其价值为v[i],现在有个容量为m的背包,如何选择物品使得装入背包的价值总量最大?

这里如何转化为0-1背包问题呢?可以定义:(假设所有数组存储下标从1开始)

sum = w[1] + w[2] + …… + w[n];

m = sum - x; (背包最大容量)

dp二维数组:

1)初始化:dp[i][0] = 0  ( 0 <= i <= n);  dp[0][j] = 0  (0 <= j <= m) 

2)状态转移方程:

if ( j < w [ i ] )      dp[ i ] [ j ] = dp[ i-1 ] [ j ] 

else       dp[ i ] [ j ] = max ( dp[ i-1 ] [ j ], dp[ i-1 ] [ j - w [ i ] ] + w [ i ] ) 

最后返回 sum - dp[n][m];

时间复杂度为O(nm)

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#define maxn 300010
using namespace std;
int dp[31][maxn]={0};
int main(){
    int n,x,sum=0,m;
    cin>>n>>x;
    int *A = (int*)malloc(sizeof(int)*(n+1));
    for(int i = 1; i <= n; i ++){
        cin>>A[i];
        sum+=A[i];
    }
    m = sum - x;
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            if(j < A[i]) dp[i][j] = dp[i-1][j];
            else dp[i][j] = max(dp[i-1][j], dp[i-1][j-A[i]]+A[i]);
        }
    }
    cout<<sum - dp[n][m]<<endl;
    return 0;
}

  

posted @   yyer  阅读(467)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2020-01-01 数据结构:选择排序
2020-01-01 数据结构:希尔排序
2020-01-01 数据结构: 快速排序
2020-01-01 数据结构:直接插入排序
点击右上角即可分享
微信分享提示