1. 程式人生 > 實用技巧 >完全揹包 包粽子

完全揹包 包粽子

包粽子,包一個純麵粉的粽子需要c 克麵粉,可以賣出 d 塊錢

有m種配料,每種配料可以對應包一種粽子,比如

第i種配料有a[i]克,包一個該配料的粽子需要配料b[i]克,麵粉c[i]克,可以賣出d[i]塊錢

問,有n克麵粉,m種配料,最多可以包粽子賣出多少塊錢?

輸入第一行為

n m c d

表示n克麵粉,m種配料,純麵粉粽子需要c克麵粉,價值為d

接下來m行,每行四個數a[i] b[i] c[i] d[i] ,分別代表該配料的總重量,包一個粽子需要的配料和麵粉以及價值

輸入樣例:

10 2 1 1

6 2 3 50

8 1 2 10

輸出樣例

151

完全揹包問題

dp[i][j] 表示使用前 i 種配料,消耗 j 克麵粉的情況下的最大價值為dp[i][j]

轉移方程為

dp[ i ][ j ]=max(dp[ i-1 ][ j ],dp[ i-1 ][ j-k*p[ i ].c ] + k*p[ i ].d );

#include<iostream>
#include<algorithm>
using namespace std;
int dp[20][1005];
struct node {
    int a, b, c, d;
}p[20];
int main()
{
    int n, m, c0, d0;
    cin >> n >> m >> c0 >> d0;
    
//把純面的粽子當成一種配料處理 p[0].a = n; p[0].b = 0; p[0].c = c0; p[0].d = d0; for (int i = 1; i <= m; i++) { cin >> p[i].a >> p[i].b >> p[i].c >> p[i].d; } for (int j = 0; j < n; j++) { dp[0][j] = 0; } for (int i = 0; i <= m; i++) { dp[i][
0] = 0; } //前i種粽子 for (int i = 0; i <= m; i++) { //消耗j克麵粉 for (int j = 1; j <=n; j++) { //在麵粉夠用的情況下,最多包k個第i種配料的粽子 for (int k = 0; k*p[i].c <= j ; k++) { //還要保證配料夠 if (k*p[i].b <= p[i].a) { dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - k * p[i].c] + k * p[i].d); } } } } cout << dp[m][n] << endl; system("pause"); return 0; }