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; } |
天晴了,起飞吧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享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 数据结构:直接插入排序