算法思路
理解题意
- 限制
- 设备数量
<-->
物品体积 - 第$i$个物品的种类有限, 且最多从中选
1
种
- 设备数量
- 目的
Max
选取物品价值
问题可抽象为分组背包问题, 且需要输出具体方案. 所以本题为: 分组背包🔗 + 背包问题求具体方案🔗 .
$DP$分析
对于第$i$类物品其物品体积为一个递增序列. 具体的分析可以参考上述链接.
代码实现
#include <iostream>
using namespace std;
const int N = 11, M = 16;
int n, m;
int w[N][M]; //v[i][k] = k. s[i] = m
int dp[N][M];
int choice[N]; //choice[i] : 第i个物品选哪一种
int main()
{
cin >> n >> m;
for( int i = 1; i <= n; i ++ )
for( int j = 1; j <= m; j ++ )
cin >> w[i][j];
for( int i = 1; i <= n; i ++ )
for( int j = 0; j <= m; j ++ )
for( int k = 0; k <= j; k ++ )
dp[i][j] = max( dp[i][j], dp[i - 1][j - k] + w[i][k] ); //v[i][k] = k
cout << dp[n][m] << endl;
int V = m; //终点为状态dp(n, V). 倒推选择方案
for( int i = n; i >= 1; i -- )
{
for( int k = 0; k <= V; k ++ )
{//选择的种类
if( dp[i][V] == dp[i - 1][V - k] + w[i][k] )
{//满足等式说明选择了第k种
choice[i] = k;
V -= k;
break;
}
}
}
for( int i = 1; i <= n; i ++ ) cout << i << ' ' << choice[i] << endl;
return 0;
}
哈哈哈昵称
😀hh