<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>0-1 knapsack &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/0-1-knapsack/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 29 Jul 2018 16:17:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.5</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>0-1 knapsack &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 879. Profitable Schemes</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-879-profitable-schemes/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-879-profitable-schemes/#comments</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 29 Jul 2018 06:06:45 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[0-1 knapsack]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=3364</guid>

					<description><![CDATA[Problem There are G people in a gang, and a list of various crimes they could commit. The i-th crime generates a profit[i] and requires group[i] gang members to participate.&#8230;]]></description>
										<content:encoded><![CDATA[<p><iframe title="花花酱 LeetCode 879. Profitable Schemes - 刷题找工作 EP212" width="500" height="375" src="https://www.youtube.com/embed/MjOIR61txFc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>There are G people in a gang, and a list of various crimes they could commit.</p>
<p>The <code>i</code>-th crime generates a <code>profit[i]</code> and requires <code>group[i]</code> gang members to participate.</p>
<p>If a gang member participates in one crime, that member can&#8217;t participate in another crime.</p>
<p>Let&#8217;s call a <em>profitable scheme</em> any subset of these crimes that generates at least <code>P</code> profit, and the total number of gang members participating in that subset of crimes is at most G.</p>
<p>How many schemes can be chosen?  Since the answer may be very large, <strong>return it modulo</strong> <code>10^9 + 7</code>.</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>G = <span id="example-input-1-1">5</span>, P = <span id="example-input-1-2">3</span>, group = <span id="example-input-1-3">[2,2]</span>, profit = <span id="example-input-1-4">[2,3]</span>
<strong>Output: </strong><span id="example-output-1">2</span>
<strong>Explanation: </strong>
To make a profit of at least 3, the gang could either commit crimes 0 and 1, or just crime 1.
In total, there are 2 schemes.
</pre>
<div>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false "><strong>Input: </strong>G = <span id="example-input-2-1">10</span>, P = <span id="example-input-2-2">5</span>, group = <span id="example-input-2-3">[2,3,5]</span>, profit = <span id="example-input-2-4">[6,7,8]</span>
<strong>Output: </strong><span id="example-output-2">7</span>
<strong>Explanation: </strong>
To make a profit of at least 5, the gang could commit any crimes, as long as they commit one.
There are 7 possible schemes: (0), (1), (2), (0,1), (0,2), (1,2), and (0,1,2).
</pre>
</div>
<p><strong>Note:</strong></p>
<ol>
<li><code>1 &lt;= G &lt;= 100</code></li>
<li><code>0 &lt;= P &lt;= 100</code></li>
<li><code>1 &lt;= group[i] &lt;= 100</code></li>
<li><code>0 &lt;= profit[i] &lt;= 100</code></li>
<li><code>1 &lt;= group.length = profit.length &lt;= 100</code></li>
</ol>
<h1><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-3372" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/07/879-ep212.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/07/879-ep212.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/07/879-ep212-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/07/879-ep212-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></h1>
<h1><strong>Solution: DP</strong></h1>
<p>Time complexity: O(KPG)</p>
<p>Space complexity: O(KPG)</p>
<p>C++</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 64 ms
class Solution {
public:
  int profitableSchemes(int G, int P, vector&lt;int&gt;&amp; group, vector&lt;int&gt;&amp; profit) {    
    const int kMod = 1000000007;
    const int K = group.size();
    // dp[k][i][j]:= # of schemes of making profit i with j people by commiting first k crimes.
    vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; dp(K + 1, vector&lt;vector&lt;int&gt;&gt;(P + 1, vector&lt;int&gt;(G + 1, 0)));
    dp[0][0][0] = 1;
    
    for (int k = 1; k &lt;= K; ++k) {      
      const int p = profit[k - 1];
      const int g = group[k - 1];
      for (int i = 0; i &lt;= P; ++i)    
        for (int j = 0; j &lt;= G; ++j)
          dp[k][i][j] = (dp[k - 1][i][j] + (j &lt; g ? 0 : dp[k - 1][max(0, i - p)][j - g])) % kMod;
    }
    return accumulate(begin(dp[K][P]), end(dp[K][P]), 0LL) % kMod;
  }
};</pre><p>Space complexity: O(PG)</p>
<p>v1: Dimension reduction by copying.</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 24 ms
class Solution {
public:
  int profitableSchemes(int G, int P, vector&lt;int&gt;&amp; group, vector&lt;int&gt;&amp; profit) {    
    const int kMod = 1000000007;
    const int K = group.size();
    // dp[i][j]:= # of schemes of making profit i with j people.
    vector&lt;vector&lt;int&gt;&gt; dp(P + 1, vector&lt;int&gt;(G + 1, 0));
    dp[0][0] = 1;
    
    for (int k = 1; k &lt;= K; ++k) {
      auto tmp = dp;
      const int p = profit[k - 1];
      const int g = group[k - 1];
      for (int i = 0; i &lt;= P; ++i)    
        for (int j = 0; j &lt;= G; ++j)
          tmp[i][j] = (tmp[i][j] + (j &lt; g ? 0 : dp[max(0, i - p)][j - g])) % kMod;
      dp.swap(tmp);
    }
    return accumulate(begin(dp[P]), end(dp[P]), 0LL) % kMod;
  }
};</pre><p>v2: Dimension reduction by using rolling array.</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 16 ms
class Solution {
public:
  int profitableSchemes(int G, int P, vector&lt;int&gt;&amp; group, vector&lt;int&gt;&amp; profit) {
    const int kMod = 1000000007;
    // dp[i][j]:= # of schemes of making profit i with j people.
    vector&lt;vector&lt;int&gt;&gt; dp(P + 1, vector&lt;int&gt;(G + 1, 0));
    dp[0][0] = 1;
    const int K = group.size();
    for (int k = 0; k &lt; K; ++k) {
      const int p = profit[k];
      const int g = group[k];
      for (int i = P; i &gt;= 0; --i) {
        const int ip = min(P, i + p);
        for (int j = G - g; j &gt;= 0; --j)
          dp[ip][j + g] = (dp[ip][j + g] + dp[i][j]) % kMod;
      }
    }
    return accumulate(begin(dp[P]), end(dp[P]), 0LL) % kMod;
  }
};</pre><p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-879-profitable-schemes/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 871. Minimum Number of Refueling Stops</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-871-minimum-number-of-refueling-stops/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-871-minimum-number-of-refueling-stops/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 15 Jul 2018 06:10:52 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[0-1 knapsack]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[knapsack]]></category>
		<category><![CDATA[min count]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=3171</guid>

					<description><![CDATA[Problem A car travels from a starting position to a destination which is target miles east of the starting position. Along the way, there are gas stations. &#8230;]]></description>
										<content:encoded><![CDATA[<p><iframe title="花花酱 LeetCode 871. Minimum Number of Refueling Stops - 刷题找工作 EP207" width="500" height="375" src="https://www.youtube.com/embed/vWTPA5zw24M?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>A car travels from a starting position to a destination which is <code>target</code> miles east of the starting position.</p>
<p>Along the way, there are gas stations.  Each <code>station[i]</code> represents a gas station that is <code>station[i][0]</code> miles east of the starting position, and has <code>station[i][1]</code> liters of gas.</p>
<p>The car starts with an infinite tank of gas, which initially has <code>startFuel</code> liters of fuel in it.  It uses 1 liter of gas per 1 mile that it drives.</p>
<p>When the car reaches a gas station, it may stop and refuel, transferring all the gas from the station into the car.</p>
<p>What is the least number of refueling stops the car must make in order to reach its destination?  If it cannot reach the destination, return <code>-1</code>.</p>
<p>Note that if the car reaches a gas station with 0 fuel left, the car can still refuel there.  If the car reaches the destination with 0 fuel left, it is still considered to have arrived.</p>
<div>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>target = <span id="example-input-1-1">1</span>, startFuel = <span id="example-input-1-2">1</span>, stations = <span id="example-input-1-3">[]</span>
<strong>Output: </strong><span id="example-output-1">0</span>
<strong>Explanation: </strong>We can reach the target without refueling.
</pre>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>target = <span id="example-input-2-1">100</span>, startFuel = <span id="example-input-2-2">1</span>, stations = <span id="example-input-2-3">[[10,100]]</span>
<strong>Output: </strong><span id="example-output-2">-1</span>
<strong>Explanation: </strong>We can't reach the target (or even the first gas station).
</pre>
<p><strong>Example 3:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>target = <span id="example-input-3-1">100</span>, startFuel = <span id="example-input-3-2">10</span>, stations = <span id="example-input-3-3">[[10,60],[20,30],[30,30],[60,40]]</span>
<strong>Output: </strong><span id="example-output-3">2</span>
<strong>Explanation: </strong>
We start with 10 liters of fuel.
We drive to position 10, expending 10 liters of fuel.  We refuel from 0 liters to 60 liters of gas.
Then, we drive from position 10 to position 60 (expending 50 liters of fuel),
and refuel from 10 liters to 50 liters of gas.  We then drive to and reach the target.
We made 2 refueling stops along the way, so we return 2.
</pre>
<p><strong>Note:</strong></p>
<ol>
<li><code>1 &lt;= target, startFuel, stations[i][1] &lt;= 10^9</code></li>
<li><code>0 &lt;= stations.length &lt;= 500</code></li>
<li><code>0 &lt; stations[0][0] &lt; stations[1][0] &lt; ... &lt; stations[stations.length-1][0] &lt; target</code></li>
</ol>
<h1><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3204" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/07/871-ep207.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/07/871-ep207.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/07/871-ep207-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/07/871-ep207-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></h1>
<h1><strong>Solution1: DP</strong></h1>
<p>Time complexity: O(n^2)</p>
<p>Space complexity: O(n)</p>
<p>C++</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 24 ms
class Solution {
public:
  int minRefuelStops(int target, int startFuel, vector&lt;vector&lt;int&gt;&gt;&amp; stations) {
    const int n = stations.size();
    // dp[i]: max distance to go with i stops.
    vector&lt;long&gt; dp(n + 1, startFuel);
    // For each station
    for (int i = 0; i &lt; n; ++i) 
      // for j stops, start from high to low to avoid reusing station i
      for (int j = i + 1; j &gt;= 1; --j) 
        if (dp[j - 1] &gt;= stations[i][0])
          // if we can reach station i with j - 1 stops,
          // we can reach dp[j - 1] + station[i][1] with j stops.
          dp[j] = max(dp[j], dp[j - 1] + stations[i][1]);
    
    for (int i = 0; i &lt; dp.size(); ++i)
      if (dp[i] &gt;= target) return i;
    return -1;
  }
};</pre><p></p>
<h1><strong>Solution2: Priority Queue</strong></h1>
<p>Time complexity: O(nlogn)</p>
<p>Space complexity: O(n)</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 16 ms
class Solution {
public:
  int minRefuelStops(int target, int startFuel, vector&lt;vector&lt;int&gt;&gt;&amp; stations) {
    int cur = startFuel;
    int stops = 0;
    int i = 0;
    priority_queue&lt;int&gt; q; // gas (high to low) of reachable stations.
    while (true) {
      if (cur &gt;= target) return stops;
      while (i &lt; stations.size() &amp;&amp; stations[i][0] &lt;= cur)
        q.push(stations[i++][1]); 
      if (q.empty()) break;
      cur += q.top(); q.pop();
      ++stops;
    }
    return -1;
  }
};</pre><p>V2: Iterator</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 12 ms
class Solution {
public:
  int minRefuelStops(int target, int startFuel, vector&lt;vector&lt;int&gt;&gt;&amp; stations) {
    int cur = startFuel;
    int stops = 0;
    priority_queue&lt;int&gt; q; // gas (high to low) of reachable stations.
    auto it = begin(stations);
    while (true) {
      if (cur &gt;= target) return stops;
      while (it != end(stations) &amp;&amp; it-&gt;at(0) &lt;= cur)
        q.push(it++-&gt;at(1));
      if (q.empty()) break;
      cur += q.top(); q.pop();
      ++stops;
    }
    return -1;
  }
};</pre><p></p>
<h1><strong>Related Problems</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-322-coin-change/">花花酱 LeetCode 322. Coin Change</a></li>
</ul>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-871-minimum-number-of-refueling-stops/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
