You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hello-algo/chapter_dynamic_programming/knapsack_problem/index.html

2765 lines
112 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!doctype html>
<html lang="zh" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="动画图解、一键运行的数据结构与算法教程">
<meta name="author" content="Krahets">
<link rel="canonical" href="https://www.hello-algo.com/chapter_dynamic_programming/knapsack_problem/">
<link rel="prev" href="../dp_problem_features/">
<link rel="next" href="../../chapter_appendix/installation/">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.4.2, mkdocs-material-9.1.11">
<title>13.3.   0-1 背包问题New - Hello 算法</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.85bb2934.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.a6bdf11c.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans+SC:300,300i,400,400i,700,700i%7CFira+Code:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Noto Sans SC";--md-code-font:"Fira Code"}</style>
<link rel="stylesheet" href="../../stylesheets/extra.css">
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="white" data-md-color-accent="indigo">
<script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#133-0-1" class="md-skip">
跳转至
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="页眉">
<a href="../.." title="Hello 算法" class="md-header__button md-logo" aria-label="Hello 算法" data-md-component="logo">
<img src="../../assets/images/logo.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Hello 算法
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
13.3. &nbsp; 0-1 背包问题New
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="white" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5c-.84 0-1.65.15-2.39.42L12 2M3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29L3.34 7m.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14L3.36 17M20.65 7l-1.77 3.79a7.023 7.023 0 0 0-2.38-4.15l4.15.36m-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29L20.64 17M12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44L12 22Z"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="grey" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3 3.19.09m3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95 2.06.05m-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31Z"/></svg>
</label>
</form>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="搜索" placeholder="搜索" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="查找">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="分享" aria-label="分享" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7 0-.24-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91 1.61 0 2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08Z"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="清空当前内容" aria-label="清空当前内容" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
正在初始化搜索引擎
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/krahets/hello-algo" title="前往仓库" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</div>
<div class="md-source__repository">
krahets/hello-algo
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="导航栏" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Hello 算法" class="md-nav__button md-logo" aria-label="Hello 算法" data-md-component="logo">
<img src="../../assets/images/logo.png" alt="logo">
</a>
Hello 算法
</label>
<div class="md-nav__source">
<a href="https://github.com/krahets/hello-algo" title="前往仓库" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</div>
<div class="md-source__repository">
krahets/hello-algo
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_1" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_preface/">0. &nbsp; &nbsp; 前言</a>
<label for="__nav_1">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_1">
<span class="md-nav__icon md-icon"></span>
0. &nbsp; &nbsp; 前言
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_preface/about_the_book/" class="md-nav__link">
0.1. &nbsp; 关于本书
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_preface/suggestions/" class="md-nav__link">
0.2. &nbsp; 如何使用本书
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_preface/summary/" class="md-nav__link">
0.3. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_introduction/">1. &nbsp; &nbsp; 初识算法</a>
<label for="__nav_2">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
1. &nbsp; &nbsp; 初识算法
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_introduction/algorithms_are_everywhere/" class="md-nav__link">
1.1. &nbsp; 算法无处不在
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_introduction/what_is_dsa/" class="md-nav__link">
1.2. &nbsp; 算法是什么
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_introduction/summary/" class="md-nav__link">
1.3. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_computational_complexity/">2. &nbsp; &nbsp; 复杂度</a>
<label for="__nav_3">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
2. &nbsp; &nbsp; 复杂度
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_computational_complexity/performance_evaluation/" class="md-nav__link">
2.1. &nbsp; 算法效率评估
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_computational_complexity/time_complexity/" class="md-nav__link">
2.2. &nbsp; 时间复杂度
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_computational_complexity/space_complexity/" class="md-nav__link">
2.3. &nbsp; 空间复杂度
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_computational_complexity/summary/" class="md-nav__link">
2.4. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_data_structure/">3. &nbsp; &nbsp; 数据结构</a>
<label for="__nav_4">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
3. &nbsp; &nbsp; 数据结构
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_data_structure/classification_of_data_structure/" class="md-nav__link">
3.1. &nbsp; 数据结构分类
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_data_structure/basic_data_types/" class="md-nav__link">
3.2. &nbsp; 基本数据类型
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_data_structure/number_encoding/" class="md-nav__link">
3.3. &nbsp; 数字编码 *
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_data_structure/character_encoding/" class="md-nav__link">
3.4. &nbsp; 字符编码 *
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_data_structure/summary/" class="md-nav__link">
3.5. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_array_and_linkedlist/">4. &nbsp; &nbsp; 数组与链表</a>
<label for="__nav_5">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
4. &nbsp; &nbsp; 数组与链表
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_array_and_linkedlist/array/" class="md-nav__link">
4.1. &nbsp; 数组
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_array_and_linkedlist/linked_list/" class="md-nav__link">
4.2. &nbsp; 链表
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_array_and_linkedlist/list/" class="md-nav__link">
4.3. &nbsp; 列表
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_array_and_linkedlist/summary/" class="md-nav__link">
4.4. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_stack_and_queue/">5. &nbsp; &nbsp; 栈与队列</a>
<label for="__nav_6">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
5. &nbsp; &nbsp; 栈与队列
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_stack_and_queue/stack/" class="md-nav__link">
5.1. &nbsp;
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_stack_and_queue/queue/" class="md-nav__link">
5.2. &nbsp; 队列
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_stack_and_queue/deque/" class="md-nav__link">
5.3. &nbsp; 双向队列
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_stack_and_queue/summary/" class="md-nav__link">
5.4. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_hashing/">6. &nbsp; &nbsp; 散列表</a>
<label for="__nav_7">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
6. &nbsp; &nbsp; 散列表
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_hashing/hash_map/" class="md-nav__link">
6.1. &nbsp; 哈希表New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_hashing/hash_collision/" class="md-nav__link">
6.2. &nbsp; 哈希冲突New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_hashing/hash_algorithm/" class="md-nav__link">
6.3. &nbsp; 哈希算法New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_hashing/summary/" class="md-nav__link">
6.4. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_tree/">7. &nbsp; &nbsp;</a>
<label for="__nav_8">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_8">
<span class="md-nav__icon md-icon"></span>
7. &nbsp; &nbsp;
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_tree/binary_tree/" class="md-nav__link">
7.1. &nbsp; 二叉树
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_tree/binary_tree_traversal/" class="md-nav__link">
7.2. &nbsp; 二叉树遍历
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_tree/array_representation_of_tree/" class="md-nav__link">
7.3. &nbsp; 二叉树数组表示
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_tree/binary_search_tree/" class="md-nav__link">
7.4. &nbsp; 二叉搜索树
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_tree/avl_tree/" class="md-nav__link">
7.5. &nbsp; AVL 树 *
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_tree/summary/" class="md-nav__link">
7.6. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_9" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_heap/">8. &nbsp; &nbsp;</a>
<label for="__nav_9">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_9">
<span class="md-nav__icon md-icon"></span>
8. &nbsp; &nbsp;
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_heap/heap/" class="md-nav__link">
8.1. &nbsp;
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_heap/build_heap/" class="md-nav__link">
8.2. &nbsp; 建堆操作
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_heap/top_k/" class="md-nav__link">
8.3. &nbsp; Top-K 问题New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_heap/summary/" class="md-nav__link">
8.4. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_10" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_graph/">9. &nbsp; &nbsp;</a>
<label for="__nav_10">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_10_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_10">
<span class="md-nav__icon md-icon"></span>
9. &nbsp; &nbsp;
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_graph/graph/" class="md-nav__link">
9.1. &nbsp;
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_graph/graph_operations/" class="md-nav__link">
9.2. &nbsp; 图基础操作
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_graph/graph_traversal/" class="md-nav__link">
9.3. &nbsp; 图的遍历
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_graph/summary/" class="md-nav__link">
9.4. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_11" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_searching/">10. &nbsp; &nbsp; 搜索</a>
<label for="__nav_11">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_11_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_11">
<span class="md-nav__icon md-icon"></span>
10. &nbsp; &nbsp; 搜索
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_searching/binary_search/" class="md-nav__link">
10.1. &nbsp; 二分查找
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_searching/binary_search_edge/" class="md-nav__link">
10.2. &nbsp; 二分查找边界
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_searching/replace_linear_by_hashing/" class="md-nav__link">
10.3. &nbsp; 哈希优化策略
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_searching/searching_algorithm_revisited/" class="md-nav__link">
10.4. &nbsp; 重识搜索算法
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_searching/summary/" class="md-nav__link">
10.5. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_12" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_sorting/">11. &nbsp; &nbsp; 排序</a>
<label for="__nav_12">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_12_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_12">
<span class="md-nav__icon md-icon"></span>
11. &nbsp; &nbsp; 排序
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_sorting/sorting_algorithm/" class="md-nav__link">
11.1. &nbsp; 排序算法
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/selection_sort/" class="md-nav__link">
11.2. &nbsp; 选择排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/bubble_sort/" class="md-nav__link">
11.3. &nbsp; 冒泡排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/insertion_sort/" class="md-nav__link">
11.4. &nbsp; 插入排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/quick_sort/" class="md-nav__link">
11.5. &nbsp; 快速排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/merge_sort/" class="md-nav__link">
11.6. &nbsp; 归并排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/heap_sort/" class="md-nav__link">
11.7. &nbsp; 堆排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/bucket_sort/" class="md-nav__link">
11.8. &nbsp; 桶排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/counting_sort/" class="md-nav__link">
11.9. &nbsp; 计数排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/radix_sort/" class="md-nav__link">
11.10. &nbsp; 基数排序
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_sorting/summary/" class="md-nav__link">
11.11. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_13" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_backtracking/">12. &nbsp; &nbsp; 回溯</a>
<label for="__nav_13">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_13">
<span class="md-nav__icon md-icon"></span>
12. &nbsp; &nbsp; 回溯
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_backtracking/backtracking_algorithm/" class="md-nav__link">
12.1. &nbsp; 回溯算法
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_backtracking/permutations_problem/" class="md-nav__link">
12.2. &nbsp; 全排列问题
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_backtracking/subset_sum_problem/" class="md-nav__link">
12.3. &nbsp; 子集和问题New
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_backtracking/n_queens_problem/" class="md-nav__link">
12.4. &nbsp; N 皇后问题
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_backtracking/summary/" class="md-nav__link">
12.5. &nbsp; 小结
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_14" checked>
<div class="md-nav__link md-nav__link--index ">
<a href="../">13. &nbsp; &nbsp; 动态规划</a>
<label for="__nav_14">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_14_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_14">
<span class="md-nav__icon md-icon"></span>
13. &nbsp; &nbsp; 动态规划
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../intro_to_dynamic_programming/" class="md-nav__link">
13.1. &nbsp; 初探动态规划New
</a>
</li>
<li class="md-nav__item">
<a href="../dp_problem_features/" class="md-nav__link">
13.2. &nbsp; DP 问题特性New
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
13.3. &nbsp; 0-1 背包问题New
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
13.3. &nbsp; 0-1 背包问题New
</a>
<nav class="md-nav md-nav--secondary" aria-label="目录">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#1331" class="md-nav__link">
13.3.1. &nbsp; 方法一:暴力搜索
</a>
</li>
<li class="md-nav__item">
<a href="#1332" class="md-nav__link">
13.3.2. &nbsp; 方法二:记忆化搜索
</a>
</li>
<li class="md-nav__item">
<a href="#1333" class="md-nav__link">
13.3.3. &nbsp; 方法三:动态规划
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_15" >
<label class="md-nav__link" for="__nav_15" id="__nav_15_label" tabindex="0">
14. &nbsp; &nbsp; 附录
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_15_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_15">
<span class="md-nav__icon md-icon"></span>
14. &nbsp; &nbsp; 附录
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../chapter_appendix/installation/" class="md-nav__link">
14.1. &nbsp; 编程环境安装
</a>
</li>
<li class="md-nav__item">
<a href="../../chapter_appendix/contribution/" class="md-nav__link">
14.2. &nbsp; 一起参与创作
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_16" >
<div class="md-nav__link md-nav__link--index ">
<a href="../../chapter_reference/">参考文献</a>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_16_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_16">
<span class="md-nav__icon md-icon"></span>
参考文献
</label>
<ul class="md-nav__list" data-md-scrollfix>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="目录">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#1331" class="md-nav__link">
13.3.1. &nbsp; 方法一:暴力搜索
</a>
</li>
<li class="md-nav__item">
<a href="#1332" class="md-nav__link">
13.3.2. &nbsp; 方法二:记忆化搜索
</a>
</li>
<li class="md-nav__item">
<a href="#1333" class="md-nav__link">
13.3.3. &nbsp; 方法三:动态规划
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/krahets/hello-algo/tree/main/docs/chapter_dynamic_programming/knapsack_problem.md" title="编辑此页" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4v-2m10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1 2.1 2.1Z"/></svg>
</a>
<h1 id="133-0-1">13.3. &nbsp; 0-1 背包问题<a class="headerlink" href="#133-0-1" title="Permanent link">&para;</a></h1>
<p>背包问题是学习动态规划的一个非常好的入门题目,其涉及到“选择与不选择”和“限制条件下的最优化”等问题,是动态规划中最常见的问题形式。</p>
<p>背包问题具有很多变种,例如 0-1 背包问题、完全背包问题、多重背包问题等。在本节中,我们先来学习最简单的 0-1 背包问题。</p>
<div class="admonition question">
<p class="admonition-title">Question</p>
<p>给定 <span class="arithmatex">\(n\)</span> 个物品,第 <span class="arithmatex">\(i\)</span> 个物品的重量为 <span class="arithmatex">\(wgt[i-1]\)</span> 、价值为 <span class="arithmatex">\(val[i-1]\)</span> ,现在有个容量为 <span class="arithmatex">\(cap\)</span> 的背包,请求解在不超过背包容量下背包中物品的最大价值。</p>
<p>请注意,物品编号 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(1\)</span> 开始计数,但数组索引从 <span class="arithmatex">\(0\)</span> 开始计数,因此物品 <span class="arithmatex">\(i\)</span> 对应重量 <span class="arithmatex">\(wgt[i-1]\)</span> 和价值 <span class="arithmatex">\(val[i-1]\)</span></p>
</div>
<p>下图给出了一个 0-1 背包的示例数据,背包内的最大价值为 <span class="arithmatex">\(220\)</span></p>
<p><img alt="0-1 背包的示例数据" src="../knapsack_problem.assets/knapsack_example.png" /></p>
<p align="center"> Fig. 0-1 背包的示例数据 </p>
<p>接下来,我们仍然先从回溯角度入手,先给出暴力搜索解法;再引入记忆化处理,得到记忆化搜索和动态规划解法。</p>
<h2 id="1331">13.3.1. &nbsp; 方法一:暴力搜索<a class="headerlink" href="#1331" title="Permanent link">&para;</a></h2>
<p>0-1 背包问题是一道典型的“选或不选”的问题0 代表不选、1 代表选。我们可以将 0-1 背包看作是一个由 <span class="arithmatex">\(n\)</span> 轮决策组成的搜索过程,对于每个物体都有不放入和放入两种决策。不放入背包,背包容量不变;放入背包,背包容量减小。由此可得:</p>
<ul>
<li><strong>状态包括物品编号 <span class="arithmatex">\(i\)</span> 和背包容量 <span class="arithmatex">\(c\)</span></strong>,记为 <span class="arithmatex">\([i, c]\)</span></li>
<li>状态 <span class="arithmatex">\([i, c]\)</span> 对应子问题“<strong><span class="arithmatex">\(i\)</span> 个物品在容量为 <span class="arithmatex">\(c\)</span> 背包中的最大价值</strong>”,解记为 <span class="arithmatex">\(dp[i, c]\)</span></li>
</ul>
<p>当我们做出物品 <span class="arithmatex">\(i\)</span> 的决策后,剩余的是前 <span class="arithmatex">\(i-1\)</span> 个物品的子问题,因此状态转移分为两种:</p>
<ul>
<li><strong>不放入物品 <span class="arithmatex">\(i\)</span></strong> :背包容量不变,状态转移至 <span class="arithmatex">\([i-1, c]\)</span> </li>
<li><strong>放入物品 <span class="arithmatex">\(i\)</span></strong> :背包容量减小 <span class="arithmatex">\(wgt[i-1]\)</span> ,价值增加 <span class="arithmatex">\(val[i-1]\)</span> ,状态转移至 <span class="arithmatex">\([i-1, c-wgt[i-1]]\)</span> </li>
</ul>
<p>上述的状态转移向我们展示了本题的「最优子结构」:<strong>最大价值 <span class="arithmatex">\(dp[i, c]\)</span> 等于不放入物品 <span class="arithmatex">\(i\)</span> 和放入物品 <span class="arithmatex">\(i\)</span> 两种方案中的价值更大的那一个</strong>。由此可推出状态转移方程:</p>
<div class="arithmatex">\[
dp[i, c] = \max(dp[i-1, c], dp[i-1, c - wgt[i-1]] + val[i-1])
\]</div>
<p>以下是暴力搜索的实现代码,其中包含以下要素:</p>
<ul>
<li><strong>递归参数</strong>:状态 <span class="arithmatex">\([i, c]\)</span> <strong>返回值</strong>:子问题的解 <span class="arithmatex">\(dp[i, c]\)</span></li>
<li><strong>终止条件</strong>:当已完成 <span class="arithmatex">\(n\)</span> 轮决策或背包无剩余容量为时,终止递归并返回价值 <span class="arithmatex">\(0\)</span></li>
<li><strong>剪枝</strong>:若当前物品重量 <span class="arithmatex">\(wgt[i - 1]\)</span> 超出剩余背包容量 <span class="arithmatex">\(c\)</span> ,则只能选择不放入背包。</li>
</ul>
<div class="tabbed-set tabbed-alternate" data-tabs="1:11"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Java</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Python</label><label for="__tabbed_1_4">Go</label><label for="__tabbed_1_5">JavaScript</label><label for="__tabbed_1_6">TypeScript</label><label for="__tabbed_1_7">C</label><label for="__tabbed_1_8">C#</label><label for="__tabbed_1_9">Swift</label><label for="__tabbed_1_10">Zig</label><label for="__tabbed_1_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.java</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="o">[</span><span class="kd">class</span><span class="err">]{</span><span class="nc">knapsack</span><span class="p">}</span><span class="o">-[</span><span class="n">func</span><span class="o">]</span><span class="p">{</span><span class="n">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.cpp</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="p">[</span><span class="k">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.py</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="k">def</span> <span class="nf">knapsack_dfs</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">c</span><span class="p">):</span>
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;0-1 背包:暴力搜索&quot;&quot;&quot;</span>
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a> <span class="c1"># 若已选完所有物品或背包无容量,则返回价值 0</span>
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a> <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">c</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a> <span class="k">return</span> <span class="mi">0</span>
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a> <span class="c1"># 若超过背包容量,则只能不放入背包</span>
<a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a> <span class="k">if</span> <span class="n">wgt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">c</span><span class="p">:</span>
<a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a> <span class="k">return</span> <span class="n">knapsack_dfs</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
<a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a> <span class="c1"># 计算不放入和放入物品 i 的最大价值</span>
<a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a> <span class="n">no</span> <span class="o">=</span> <span class="n">knapsack_dfs</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
<a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a> <span class="n">yes</span> <span class="o">=</span> <span class="n">knapsack_dfs</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span> <span class="o">-</span> <span class="n">wgt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="n">val</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a> <span class="c1"># 返回两种方案中价值更大的那一个</span>
<a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a> <span class="k">return</span> <span class="nb">max</span><span class="p">(</span><span class="n">no</span><span class="p">,</span> <span class="n">yes</span><span class="p">)</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.go</span><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="p">[</span><span class="nx">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="nx">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.js</span><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.ts</span><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.c</span><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.cs</span><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="na">[class]</span><span class="p">{</span><span class="n">knapsack</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.swift</span><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="n">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.zig</span><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.dart</span><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFS</span><span class="p">}</span>
</code></pre></div>
</div>
</div>
</div>
<p>如下图所示,由于每个物品都会产生不选和选两条搜索分支,因此最差时间复杂度为 <span class="arithmatex">\(O(2^n)\)</span></p>
<p>观察递归树,容易发现其中存在一些「重叠子问题」。而当物品较多、背包容量较大,尤其是当相同重量的物品较多时,重叠子问题的数量将会大幅增多。</p>
<p><img alt="0-1 背包的暴力搜索递归树" src="../knapsack_problem.assets/knapsack_dfs.png" /></p>
<p align="center"> Fig. 0-1 背包的暴力搜索递归树 </p>
<h2 id="1332">13.3.2. &nbsp; 方法二:记忆化搜索<a class="headerlink" href="#1332" title="Permanent link">&para;</a></h2>
<p>为了防止重复求解重叠子问题,我们借助一个记忆列表 <code>mem</code> 来记录子问题的解,其中 <code>mem[i][c]</code> 表示前 <span class="arithmatex">\(i\)</span> 个物品在容量为 <span class="arithmatex">\(c\)</span> 背包中的最大价值。当再次遇到相同子问题时,直接从 <code>mem</code> 中获取记录。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="2:11"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><input id="__tabbed_2_7" name="__tabbed_2" type="radio" /><input id="__tabbed_2_8" name="__tabbed_2" type="radio" /><input id="__tabbed_2_9" name="__tabbed_2" type="radio" /><input id="__tabbed_2_10" name="__tabbed_2" type="radio" /><input id="__tabbed_2_11" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Java</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Python</label><label for="__tabbed_2_4">Go</label><label for="__tabbed_2_5">JavaScript</label><label for="__tabbed_2_6">TypeScript</label><label for="__tabbed_2_7">C</label><label for="__tabbed_2_8">C#</label><label for="__tabbed_2_9">Swift</label><label for="__tabbed_2_10">Zig</label><label for="__tabbed_2_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.java</span><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="o">[</span><span class="kd">class</span><span class="err">]{</span><span class="nc">knapsack</span><span class="p">}</span><span class="o">-[</span><span class="n">func</span><span class="o">]</span><span class="p">{</span><span class="n">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.cpp</span><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="p">[</span><span class="k">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.py</span><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="k">def</span> <span class="nf">knapsack_dfs_mem</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">mem</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">c</span><span class="p">):</span>
<a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;0-1 背包:记忆化搜索&quot;&quot;&quot;</span>
<a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a> <span class="c1"># 若已选完所有物品或背包无容量,则返回价值 0</span>
<a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a> <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">c</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a id="__codelineno-13-5" name="__codelineno-13-5" href="#__codelineno-13-5"></a> <span class="k">return</span> <span class="mi">0</span>
<a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a> <span class="c1"># 若已有记录,则直接返回</span>
<a id="__codelineno-13-7" name="__codelineno-13-7" href="#__codelineno-13-7"></a> <span class="k">if</span> <span class="n">mem</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
<a id="__codelineno-13-8" name="__codelineno-13-8" href="#__codelineno-13-8"></a> <span class="k">return</span> <span class="n">mem</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="p">]</span>
<a id="__codelineno-13-9" name="__codelineno-13-9" href="#__codelineno-13-9"></a> <span class="c1"># 若超过背包容量,则只能不放入背包</span>
<a id="__codelineno-13-10" name="__codelineno-13-10" href="#__codelineno-13-10"></a> <span class="k">if</span> <span class="n">wgt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">c</span><span class="p">:</span>
<a id="__codelineno-13-11" name="__codelineno-13-11" href="#__codelineno-13-11"></a> <span class="k">return</span> <span class="n">knapsack_dfs_mem</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">mem</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
<a id="__codelineno-13-12" name="__codelineno-13-12" href="#__codelineno-13-12"></a> <span class="c1"># 计算不放入和放入物品 i 的最大价值</span>
<a id="__codelineno-13-13" name="__codelineno-13-13" href="#__codelineno-13-13"></a> <span class="n">no</span> <span class="o">=</span> <span class="n">knapsack_dfs_mem</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">mem</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
<a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a> <span class="n">yes</span> <span class="o">=</span> <span class="n">knapsack_dfs_mem</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">mem</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span> <span class="o">-</span> <span class="n">wgt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="n">val</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<a id="__codelineno-13-15" name="__codelineno-13-15" href="#__codelineno-13-15"></a> <span class="c1"># 记录并返回两种方案中价值更大的那一个</span>
<a id="__codelineno-13-16" name="__codelineno-13-16" href="#__codelineno-13-16"></a> <span class="n">mem</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">no</span><span class="p">,</span> <span class="n">yes</span><span class="p">)</span>
<a id="__codelineno-13-17" name="__codelineno-13-17" href="#__codelineno-13-17"></a> <span class="k">return</span> <span class="n">mem</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="p">]</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.go</span><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="p">[</span><span class="nx">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="nx">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.js</span><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.ts</span><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.c</span><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.cs</span><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="na">[class]</span><span class="p">{</span><span class="n">knapsack</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.swift</span><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="n">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.zig</span><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.dart</span><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDFSMem</span><span class="p">}</span>
</code></pre></div>
</div>
</div>
</div>
<p>引入记忆化之后,所有子问题最多只被计算一次,<strong>因此时间复杂度取决于子问题数量</strong>,也就是 <span class="arithmatex">\(O(n \times cap)\)</span></p>
<p><img alt="0-1 背包的记忆化搜索递归树" src="../knapsack_problem.assets/knapsack_dfs_mem.png" /></p>
<p align="center"> Fig. 0-1 背包的记忆化搜索递归树 </p>
<h2 id="1333">13.3.3. &nbsp; 方法三:动态规划<a class="headerlink" href="#1333" title="Permanent link">&para;</a></h2>
<p>接下来就是体力活了,我们将“从顶至底”的记忆化搜索代码译写为“从底至顶”的动态规划代码。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="3:11"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Java</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Python</label><label for="__tabbed_3_4">Go</label><label for="__tabbed_3_5">JavaScript</label><label for="__tabbed_3_6">TypeScript</label><label for="__tabbed_3_7">C</label><label for="__tabbed_3_8">C#</label><label for="__tabbed_3_9">Swift</label><label for="__tabbed_3_10">Zig</label><label for="__tabbed_3_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.java</span><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="o">[</span><span class="kd">class</span><span class="err">]{</span><span class="nc">knapsack</span><span class="p">}</span><span class="o">-[</span><span class="n">func</span><span class="o">]</span><span class="p">{</span><span class="n">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.cpp</span><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="p">[</span><span class="k">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.py</span><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="k">def</span> <span class="nf">knapsack_dp</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">cap</span><span class="p">):</span>
<a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;0-1 背包:动态规划&quot;&quot;&quot;</span>
<a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a> <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">wgt</span><span class="p">)</span>
<a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a> <span class="c1"># 初始化 dp 列表</span>
<a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-5"></a> <span class="n">dp</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">cap</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>
<a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-6"></a> <span class="c1"># 状态转移</span>
<a id="__codelineno-24-7" name="__codelineno-24-7" href="#__codelineno-24-7"></a> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
<a id="__codelineno-24-8" name="__codelineno-24-8" href="#__codelineno-24-8"></a> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">cap</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
<a id="__codelineno-24-9" name="__codelineno-24-9" href="#__codelineno-24-9"></a> <span class="k">if</span> <span class="n">wgt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">c</span><span class="p">:</span>
<a id="__codelineno-24-10" name="__codelineno-24-10" href="#__codelineno-24-10"></a> <span class="c1"># 若超过背包容量,则不选物品 i</span>
<a id="__codelineno-24-11" name="__codelineno-24-11" href="#__codelineno-24-11"></a> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="n">c</span><span class="p">]</span>
<a id="__codelineno-24-12" name="__codelineno-24-12" href="#__codelineno-24-12"></a> <span class="k">else</span><span class="p">:</span>
<a id="__codelineno-24-13" name="__codelineno-24-13" href="#__codelineno-24-13"></a> <span class="c1"># 不选和选物品 i 这两种方案的较大值</span>
<a id="__codelineno-24-14" name="__codelineno-24-14" href="#__codelineno-24-14"></a> <span class="n">dp</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="n">c</span> <span class="o">-</span> <span class="n">wgt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]]</span> <span class="o">+</span> <span class="n">val</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">][</span><span class="n">c</span><span class="p">])</span>
<a id="__codelineno-24-15" name="__codelineno-24-15" href="#__codelineno-24-15"></a> <span class="k">return</span> <span class="n">dp</span><span class="p">[</span><span class="n">n</span><span class="p">][</span><span class="n">cap</span><span class="p">]</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.go</span><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="p">[</span><span class="nx">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="nx">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.js</span><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.ts</span><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.c</span><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.cs</span><pre><span></span><code><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="na">[class]</span><span class="p">{</span><span class="n">knapsack</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.swift</span><pre><span></span><code><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="n">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.zig</span><pre><span></span><code><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.dart</span><pre><span></span><code><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDP</span><span class="p">}</span>
</code></pre></div>
</div>
</div>
</div>
<p>观察下图,动态规划的过程本质上就是填充 <span class="arithmatex">\(dp\)</span> 列表(矩阵)的过程,时间复杂度也为 <span class="arithmatex">\(O(n \times cap)\)</span></p>
<div class="tabbed-set tabbed-alternate" data-tabs="4:14"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><input id="__tabbed_4_3" name="__tabbed_4" type="radio" /><input id="__tabbed_4_4" name="__tabbed_4" type="radio" /><input id="__tabbed_4_5" name="__tabbed_4" type="radio" /><input id="__tabbed_4_6" name="__tabbed_4" type="radio" /><input id="__tabbed_4_7" name="__tabbed_4" type="radio" /><input id="__tabbed_4_8" name="__tabbed_4" type="radio" /><input id="__tabbed_4_9" name="__tabbed_4" type="radio" /><input id="__tabbed_4_10" name="__tabbed_4" type="radio" /><input id="__tabbed_4_11" name="__tabbed_4" type="radio" /><input id="__tabbed_4_12" name="__tabbed_4" type="radio" /><input id="__tabbed_4_13" name="__tabbed_4" type="radio" /><input id="__tabbed_4_14" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">&lt;1&gt;</label><label for="__tabbed_4_2">&lt;2&gt;</label><label for="__tabbed_4_3">&lt;3&gt;</label><label for="__tabbed_4_4">&lt;4&gt;</label><label for="__tabbed_4_5">&lt;5&gt;</label><label for="__tabbed_4_6">&lt;6&gt;</label><label for="__tabbed_4_7">&lt;7&gt;</label><label for="__tabbed_4_8">&lt;8&gt;</label><label for="__tabbed_4_9">&lt;9&gt;</label><label for="__tabbed_4_10">&lt;10&gt;</label><label for="__tabbed_4_11">&lt;11&gt;</label><label for="__tabbed_4_12">&lt;12&gt;</label><label for="__tabbed_4_13">&lt;13&gt;</label><label for="__tabbed_4_14">&lt;14&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<p><img alt="0-1 背包的动态规划过程" src="../knapsack_problem.assets/knapsack_dp_step1.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step2" src="../knapsack_problem.assets/knapsack_dp_step2.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step3" src="../knapsack_problem.assets/knapsack_dp_step3.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step4" src="../knapsack_problem.assets/knapsack_dp_step4.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step5" src="../knapsack_problem.assets/knapsack_dp_step5.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step6" src="../knapsack_problem.assets/knapsack_dp_step6.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step7" src="../knapsack_problem.assets/knapsack_dp_step7.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step8" src="../knapsack_problem.assets/knapsack_dp_step8.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step9" src="../knapsack_problem.assets/knapsack_dp_step9.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step10" src="../knapsack_problem.assets/knapsack_dp_step10.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step11" src="../knapsack_problem.assets/knapsack_dp_step11.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step12" src="../knapsack_problem.assets/knapsack_dp_step12.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step13" src="../knapsack_problem.assets/knapsack_dp_step13.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_step14" src="../knapsack_problem.assets/knapsack_dp_step14.png" /></p>
</div>
</div>
</div>
<p><strong>接下来考虑状态压缩</strong>。以上代码中的 <span class="arithmatex">\(dp\)</span> 矩阵占用 <span class="arithmatex">\(O(n \times cap)\)</span> 空间。由于每个状态都只与其上一行的状态有关,因此我们可以使用两个数组滚动前进,将空间复杂度从 <span class="arithmatex">\(O(n^2)\)</span> 将低至 <span class="arithmatex">\(O(n)\)</span> 。代码省略,有兴趣的同学可以自行实现。</p>
<p>那么,我们是否可以仅用一个数组实现状态压缩呢?观察可知,每个状态都是由左上方或正上方的格子转移过来的。假设只有一个数组,当遍历到第 <span class="arithmatex">\(i\)</span> 行时,该数组存储的仍然是第 <span class="arithmatex">\(i-1\)</span> 行的状态,为了避免左边区域的格子被覆盖,我们应采取倒序遍历,这样方可实现正确的状态转移。</p>
<p>以下动画展示了在单个数组下从第 <span class="arithmatex">\(i=1\)</span> 行转换至第 <span class="arithmatex">\(i=2\)</span> 行的过程。建议你思考一下正序遍历和倒序遍历的区别。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="5:6"><input checked="checked" id="__tabbed_5_1" name="__tabbed_5" type="radio" /><input id="__tabbed_5_2" name="__tabbed_5" type="radio" /><input id="__tabbed_5_3" name="__tabbed_5" type="radio" /><input id="__tabbed_5_4" name="__tabbed_5" type="radio" /><input id="__tabbed_5_5" name="__tabbed_5" type="radio" /><input id="__tabbed_5_6" name="__tabbed_5" type="radio" /><div class="tabbed-labels"><label for="__tabbed_5_1">&lt;1&gt;</label><label for="__tabbed_5_2">&lt;2&gt;</label><label for="__tabbed_5_3">&lt;3&gt;</label><label for="__tabbed_5_4">&lt;4&gt;</label><label for="__tabbed_5_5">&lt;5&gt;</label><label for="__tabbed_5_6">&lt;6&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<p><img alt="0-1 背包的状态压缩后的动态规划过程" src="../knapsack_problem.assets/knapsack_dp_comp_step1.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_comp_step2" src="../knapsack_problem.assets/knapsack_dp_comp_step2.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_comp_step3" src="../knapsack_problem.assets/knapsack_dp_comp_step3.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_comp_step4" src="../knapsack_problem.assets/knapsack_dp_comp_step4.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_comp_step5" src="../knapsack_problem.assets/knapsack_dp_comp_step5.png" /></p>
</div>
<div class="tabbed-block">
<p><img alt="knapsack_dp_comp_step6" src="../knapsack_problem.assets/knapsack_dp_comp_step6.png" /></p>
</div>
</div>
</div>
<p>如以下代码所示,我们仅需将 <span class="arithmatex">\(dp\)</span> 列表的第一维 <span class="arithmatex">\(i\)</span> 直接删除,并且将内循环修改为倒序遍历即可。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="6:11"><input checked="checked" id="__tabbed_6_1" name="__tabbed_6" type="radio" /><input id="__tabbed_6_2" name="__tabbed_6" type="radio" /><input id="__tabbed_6_3" name="__tabbed_6" type="radio" /><input id="__tabbed_6_4" name="__tabbed_6" type="radio" /><input id="__tabbed_6_5" name="__tabbed_6" type="radio" /><input id="__tabbed_6_6" name="__tabbed_6" type="radio" /><input id="__tabbed_6_7" name="__tabbed_6" type="radio" /><input id="__tabbed_6_8" name="__tabbed_6" type="radio" /><input id="__tabbed_6_9" name="__tabbed_6" type="radio" /><input id="__tabbed_6_10" name="__tabbed_6" type="radio" /><input id="__tabbed_6_11" name="__tabbed_6" type="radio" /><div class="tabbed-labels"><label for="__tabbed_6_1">Java</label><label for="__tabbed_6_2">C++</label><label for="__tabbed_6_3">Python</label><label for="__tabbed_6_4">Go</label><label for="__tabbed_6_5">JavaScript</label><label for="__tabbed_6_6">TypeScript</label><label for="__tabbed_6_7">C</label><label for="__tabbed_6_8">C#</label><label for="__tabbed_6_9">Swift</label><label for="__tabbed_6_10">Zig</label><label for="__tabbed_6_11">Dart</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.java</span><pre><span></span><code><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="o">[</span><span class="kd">class</span><span class="err">]{</span><span class="nc">knapsack</span><span class="p">}</span><span class="o">-[</span><span class="n">func</span><span class="o">]</span><span class="p">{</span><span class="n">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.cpp</span><pre><span></span><code><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="p">[</span><span class="k">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.py</span><pre><span></span><code><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a><span class="k">def</span> <span class="nf">knapsack_dp_comp</span><span class="p">(</span><span class="n">wgt</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">cap</span><span class="p">):</span>
<a id="__codelineno-35-2" name="__codelineno-35-2" href="#__codelineno-35-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;0-1 背包:状态压缩后的动态规划&quot;&quot;&quot;</span>
<a id="__codelineno-35-3" name="__codelineno-35-3" href="#__codelineno-35-3"></a> <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">wgt</span><span class="p">)</span>
<a id="__codelineno-35-4" name="__codelineno-35-4" href="#__codelineno-35-4"></a> <span class="c1"># 初始化 dp 列表</span>
<a id="__codelineno-35-5" name="__codelineno-35-5" href="#__codelineno-35-5"></a> <span class="n">dp</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">cap</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-35-6" name="__codelineno-35-6" href="#__codelineno-35-6"></a> <span class="c1"># 状态转移</span>
<a id="__codelineno-35-7" name="__codelineno-35-7" href="#__codelineno-35-7"></a> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
<a id="__codelineno-35-8" name="__codelineno-35-8" href="#__codelineno-35-8"></a> <span class="c1"># 倒序遍历</span>
<a id="__codelineno-35-9" name="__codelineno-35-9" href="#__codelineno-35-9"></a> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">cap</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">):</span>
<a id="__codelineno-35-10" name="__codelineno-35-10" href="#__codelineno-35-10"></a> <span class="k">if</span> <span class="n">wgt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">c</span><span class="p">:</span>
<a id="__codelineno-35-11" name="__codelineno-35-11" href="#__codelineno-35-11"></a> <span class="c1"># 若超过背包容量,则不选物品 i</span>
<a id="__codelineno-35-12" name="__codelineno-35-12" href="#__codelineno-35-12"></a> <span class="n">dp</span><span class="p">[</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="n">dp</span><span class="p">[</span><span class="n">c</span><span class="p">]</span>
<a id="__codelineno-35-13" name="__codelineno-35-13" href="#__codelineno-35-13"></a> <span class="k">else</span><span class="p">:</span>
<a id="__codelineno-35-14" name="__codelineno-35-14" href="#__codelineno-35-14"></a> <span class="c1"># 不选和选物品 i 这两种方案的较大值</span>
<a id="__codelineno-35-15" name="__codelineno-35-15" href="#__codelineno-35-15"></a> <span class="n">dp</span><span class="p">[</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">dp</span><span class="p">[</span><span class="n">c</span> <span class="o">-</span> <span class="n">wgt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]]</span> <span class="o">+</span> <span class="n">val</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">],</span> <span class="n">dp</span><span class="p">[</span><span class="n">c</span><span class="p">])</span>
<a id="__codelineno-35-16" name="__codelineno-35-16" href="#__codelineno-35-16"></a> <span class="k">return</span> <span class="n">dp</span><span class="p">[</span><span class="n">cap</span><span class="p">]</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.go</span><pre><span></span><code><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a><span class="p">[</span><span class="nx">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="nx">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.js</span><pre><span></span><code><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.ts</span><pre><span></span><code><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="nx">func</span><span class="p">]{</span><span class="nx">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.c</span><pre><span></span><code><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.cs</span><pre><span></span><code><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a><span class="na">[class]</span><span class="p">{</span><span class="n">knapsack</span><span class="p">}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.swift</span><pre><span></span><code><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a><span class="p">[</span><span class="kd">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="kd">func</span><span class="p">]{</span><span class="n">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.zig</span><pre><span></span><code><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">knapsack.dart</span><pre><span></span><code><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a><span class="p">[</span><span class="n">class</span><span class="p">]{}</span><span class="o">-</span><span class="p">[</span><span class="n">func</span><span class="p">]{</span><span class="n">knapsackDPComp</span><span class="p">}</span>
</code></pre></div>
</div>
</div>
</div>
<h2 id="__comments">评论</h2>
<!-- Insert generated snippet here -->
<script
src="https://giscus.app/client.js"
data-repo="krahets/hello-algo"
data-repo-id="R_kgDOIXtSqw"
data-category="Announcements"
data-category-id="DIC_kwDOIXtSq84CSZk_"
data-mapping="pathname"
data-strict="1"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="preferred_color_scheme"
data-lang="zh-CN"
crossorigin="anonymous"
async
>
</script>
<!-- Synchronize Giscus theme with palette -->
<script>
var giscus = document.querySelector("script[src*=giscus]")
/* Set palette on initial load */
var palette = __md_get("__palette")
if (palette && typeof palette.color === "object") {
var theme = palette.color.scheme === "slate" ? "dark" : "light"
giscus.setAttribute("data-theme", theme)
}
/* Register event handlers after documented loaded */
document.addEventListener("DOMContentLoaded", function() {
var ref = document.querySelector("[data-md-component=palette]")
ref.addEventListener("change", function() {
var palette = __md_get("__palette")
if (palette && typeof palette.color === "object") {
var theme = palette.color.scheme === "slate" ? "dark" : "light"
/* Instruct Giscus to change theme */
var frame = document.querySelector(".giscus-frame")
frame.contentWindow.postMessage(
{ giscus: { setConfig: { theme } } },
"https://giscus.app"
)
}
})
})
</script>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var tab,labels=set.querySelector(".tabbed-labels");for(tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12Z"/></svg>
回到页面顶部
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="页脚" >
<a href="../dp_problem_features/" class="md-footer__link md-footer__link--prev" aria-label="上一页: 13.2. &amp;nbsp; DP 问题特性New" rel="prev">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
上一页
</span>
<div class="md-ellipsis">
13.2. &nbsp; DP 问题特性New
</div>
</div>
</a>
<a href="../../chapter_appendix/installation/" class="md-footer__link md-footer__link--next" aria-label="下一页: 14.1. &amp;nbsp; 编程环境安装" rel="next">
<div class="md-footer__title">
<span class="md-footer__direction">
下一页
</span>
<div class="md-ellipsis">
14.1. &nbsp; 编程环境安装
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4Z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2023 Krahets
</div>
</div>
<div class="md-social">
<a href="https://github.com/krahets" target="_blank" rel="noopener" title="github.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</a>
<a href="https://twitter.com/krahets" target="_blank" rel="noopener" title="twitter.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
</a>
<a href="https://leetcode.cn/u/jyd/" target="_blank" rel="noopener" title="leetcode.cn" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M392.8 1.2c-17-4.9-34.7 5-39.6 22l-128 448c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l128-448c4.9-17-5-34.7-22-39.6zm80.6 120.1c-12.5 12.5-12.5 32.8 0 45.3l89.3 89.4-89.4 89.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-112-112c-12.5-12.5-32.8-12.5-45.3 0zm-306.7 0c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l112 112c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256l89.4-89.4c12.5-12.5 12.5-32.8 0-45.3z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": ["content.action.edit", "content.code.annotate", "content.code.copy", "content.tabs.link", "content.tooltips", "navigation.indexes", "navigation.top", "navigation.footer", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../assets/javascripts/workers/search.208ed371.min.js", "translations": {"clipboard.copied": "\u5df2\u590d\u5236", "clipboard.copy": "\u590d\u5236", "search.result.more.one": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.more.other": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 # \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.none": "\u6ca1\u6709\u627e\u5230\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.one": "\u627e\u5230 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.other": "# \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.placeholder": "\u952e\u5165\u4ee5\u5f00\u59cb\u641c\u7d22", "search.result.term.missing": "\u7f3a\u5c11", "select.version": "\u9009\u62e9\u5f53\u524d\u7248\u672c"}}</script>
<script src="../../assets/javascripts/bundle.fac441b0.min.js"></script>
<script src="../../javascripts/mathjax.js"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</body>
</html>