leetcode(c++)(背包问题)
#include <iostream> #include <vector> #include <numeric> using namespace std; bool canPartition(const vector<int>& nums) { int sum = accumulate(nums.begin(),nums.end(),0); if(sum % 2 != 0)return false; sum /= 2; int n = nums.size(); vector<vector<bool>>dp(n + 1,vector<bool>(sum + 1)); for(int i = 0; i <= n; ++i)dp[i][0] = true; for(int i = 1; i <= n; ++i) { for(int j = 1; j <= sum; ++j) { dp[i][j] = dp[i-1][j]; if(j - nums[i-1] >= 0) dp[i][j] = dp[i][j] | dp[i-1][j - nums[i-1]]; } } return dp[n][sum]; } int findMaxFrom(const vector<string>& strs,int m, int n) { vector<vector<int>>dp(m+1,vector<int>(n+1)); for(auto str:strs) { int one = 0, zero = 0; for(int i = 0; i < str.size(); ++i) { if(str[i] == '0')++zero; else ++one; } for(int i = m; i >= zero; --i) { for(int j = n; j >= one; --j) { dp[i][j] = max(dp[i][j],dp[i-zero][j-one] + 1); } } } return dp[m][n]; } int subSet(const vector<int>& nums, int S) { int n = nums.size(); vector<vector<int>>dp(n+1,vector<int>(S+1)); dp[0][0] = 1; for(int i = 1; i <= n; ++i) { for(int j = 0; j <= S; ++j) { dp[i][j] = dp[i - 1][j]; if(j - nums[i-1] >= 0)dp[i][j]+=dp[i-1][j-nums[i-1]]; } } return dp[n][S]; } int findTargetSumWays(const vector<int>& nums, int S) { int sum = accumulate(nums.begin(),nums.end(),0); if(S > sum || (S + sum) % 2 == 1) return 0; return subSet(nums,(sum + S) / 2); } int lastStoneWeightII(const vector<int>& nums) { int sum = accumulate(nums.begin(),nums.end(),0); int target = sum / 2; int n = nums.size(); vector<vector<int>>dp(n + 1, vector<int>(target + 1)); for(int i = 1; i <= n; ++i) { for(int j = 1; j <= target; ++j) { dp[i][j] = dp[i-1][j]; if(j - nums[i-1] >= 0) { dp[i][j] = max(nums[i-1] + dp[i-1][j-nums[i-1]],dp[i-1][j]); } } } return sum - 2*dp[n][target]; } int change(const vector<int>& nums,int amount) { int n = nums.size(); vector<vector<int>>dp(n + 1, vector<int>(amount + 1)); for(int i = 0; i <= n; ++i) { dp[i][0] = 1; } for(int i = 1; i <= n; ++i) { for(int j = 1; j <= amount; ++j) { dp[i][j] = dp[i-1][j]; if(j - nums[i-1] >= 0) { dp[i][j] += dp[i][j-nums[i-1]]; } } } return dp[n][amount]; } int coinChange(const vector<int>& coins, int amount) { int n = coins.size(); vector<vector<int>>dp(n + 1, vector<int>(amount + 1,INT_MAX)); for(int i = 0; i <= n; ++i) { dp[i][0] = 0; } for(int i = 1; i <= n; ++i) { for(int j = 0; j <= amount; ++j) { dp[i][j] = dp[i-1][j]; if(j >= coins[i-1] && dp[i][j-coins[i-1]]!= INT_MAX) { dp[i][j] = min(dp[i][j],dp[i][j-coins[i-1]]+1); } } } return dp[n][amount] == INT_MAX ? -1:dp[n][amount]; } int change1(const vector<int>& nums, int amount) { int n = nums.size(); vector<vector<int>>dp(n + 1,vector<int>(amount+1)); for(int i = 0; i <= n; ++i) { dp[i][0] = 1; } for(int i = 1; i <= n; ++i) { for(int j = 1;j <= amount ; ++j) { dp[i][j] = dp[i-1][j]; if(j - nums[i-1] >= 0)dp[i][j]+=dp[i][j-nums[i-1]]; } } return dp[n][amount]; } int canPartition(int n, const vector<int>&prices,const vector<int>&weight,const vector<int>& amount) { int n0 = prices.size(); vector<vector<int>>dp(n0+1,vector<int>(n+1)); for(int i = 1; i <= n0; ++i) { for(int j = 1; j <= n; ++j) { dp[i][j] = dp[i-1][j]; for(int k = 0; k <= amount[i-1]; ++k) { if(j - k * prices[i-1] >= 0) { dp[i][j] = max(dp[i][j],dp[i-1][j-k*prices[i-1]] + k * weight[i-1]); } } } } return dp[n0][n]; } int main() { //LeetCode416 vector<int>v{1,5,11,5}; cout << canPartition(v) << endl; //LeetCode474 vector<string>strs{"10","0001","111001","1","0"}; int m = 5, n = 3; cout << findMaxFrom(strs,m,n) << endl; //LeetCode494 vector<int>nums{1,1,1,1,1}; int s = 3; cout << findTargetSumWays(nums,s) << endl; //LeetCode1049 vector<int>numss{2,7,4,1,8,1}; cout << lastStoneWeightII(numss) << endl; //完全背包问题 //LeetCode322 vector<int>coins{1,2,5}; int amount =11; cout << coinChange(coins,amount) << endl; //LeetCode518 vector<int>coin{1,2,5}; amount = 5; cout << change1(coin,amount) << endl; //LintCode798 vector<int>prices{3,2}; vector<int>weights{300,160}; vector<int>amounts{1,6}; n = 8; cout << canPartition(n,prices,weights,amounts) << endl; return 0; }