hihocoder1364背包问题

    科技2022-07-13  127

    描述 小Hi在游乐园中获得了M张奖券,这些奖券可以用来兑换奖品。

    可供兑换的奖品一共有N件。第i件奖品需要Wi张奖券才能兑换到,其价值是Pi。

    小Hi使用不超过M张奖券所能兑换到的最大奖品总价值是多少?

    输入 第一行两个整数N,M。

    接下来N行,每行两个整数Wi,Pi。

    对于 50%的数据: 1≤N,M≤1000

    对于 100%的数据: 1≤N,M≤100000, 1≤Pi,Wi≤10。

    输出 一行一个整数,表示最大的价值。

    样例输入 3 10 2 3 8 8 10 10 样例输出 11

    #include <iostream> #include <string.h> #include <math.h> using namespace std; int main() { int N, M, u[11][11], dp[100005]; memset(u, 0, sizeof(u)); //string.h memset(dp, 0, sizeof(dp)); cin >> N >> M; int max_w = 0, max_p = 0; for (int i = 0; i < N; i++) { int w, p; cin >> w >> p; if (w > max_w) max_w = w; if (p > max_p) max_p = p; u[w][p]++; } for (int i = 1; i <= max_w; i++) { for (int j = 1; j <= max_p; j++) { int tem = 1; while (u[i][j] > 0) { int num; if (u[i][j] >= tem) { u[i][j] -= tem; num = tem; } else { num = u[i][j]; u[i][j] = 0; } tem *= 2; //2倍增长 for (int k = M; k >= i * num; k--) dp[k] = max(dp[k], dp[k - i * num] + j * num); } } } cout << dp[M] << endl; return 0; }

    核心是 dp[k] = max(dp[k], dp[k - i * num] + j * num);

    为什么用二倍增长法?提高遍历效率。 这里以u[2][*]举例: M=10, 因为第一次更新时是 10->9->8->7->…2

    hicode官网 http://hihocoder.com/hiho 转载于 https://www.cnblogs.com/wxyww/p/10313839.html

    Processed: 0.012, SQL: 8