16 篇文章 0 订阅

# 1.Leetcode 53

class Solution {
public:
int maxSubArray(vector<int>& nums)
{
//保存以当前字符结尾的最大连续字段和
int dp[40000];
//base case
dp[0]=nums[0];
for(int i=1;i<nums.size();i++)
{
dp[i]=max(nums[i],dp[i-1]+nums[i]);
}
int max=dp[0];
for(int j=1;j<nums.size();j++)
{
//cout<<dp[j]<<endl;
if(max<dp[j])
max=dp[j];
}
return max;
}
};


# 2.Leetcode416 Partition Equal Subset Sum

Given a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
【KEY】：dp[i][j]表示对于前i个物体，存在某种方法，刚好装下j容量的背包

int[][] dp[N+1][W+1]
dp[0][..] = 0
dp[..][0] = 0

for i in [1..N]:
for j in [1..W]:
if (j - nums[i - 1] < 0) {
// 背包容量不足，不能装入第 i 个物品
dp[i][j] = dp[i - 1][j];
} else {
// 装入或不装入背包
dp[i][j] = dp[i - 1][j] || dp[i - 1][j-nums[i-1]];
}

return dp[N][W]


class Solution {
public:
bool canPartition(vector<int>& nums)
{

int sum=0;
for(int i=0;i<nums.size();i++)
{
sum+=nums[i];
}
if(sum%2!=0)
return false;
int ans=sum/2;
cout<<ans;
int size=nums.size();
int dp[size+1][ans+1];
memset(dp,0,sizeof(dp));
//base case
// dp[0][0]=1;
for(int i=0;i<=size;i++)
{
dp[i][0]=1;
}
for(int i=1;i<=ans;i++)
{
dp[0][i]=0;
}
int save;
//dp[i][j]表示对于前i个物体，存在某种方法，刚好装下j容量的背包
for(int i=1;i<=nums.size();i++)
{
for(int j=1;j<=ans;j++)
{
save=nums[i-1];
if(j-save<0)
{
dp[i][j]=dp[i-1][j];
continue;
}
if(dp[i-1][j-save]==1)
dp[i][j]=1;
else
dp[i][j]=dp[i-1][j];
}
}

if(dp[size][ans]==1)
return true;
else return false;

}
};


# 3.【LeetCode518】Coin Change 2

You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.

Return the number of combinations that make up that amount. If that amount of money cannot be made up by any combination of the coins, return 0.

You may assume that you have an infinite number of each kind of coin.

The answer is guaranteed to fit into a signed 32-bit integer.

Example 1:

Input: amount = 5, coins = [1,2,5]
Output: 4
Explanation: there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1


Example 2:

Input: amount = 3, coins = [2]
Output: 0
Explanation: the amount of 3 cannot be made up just with coins of 2.


Example 3:

Input: amount = 10, coins = [10]
Output: 1


【注意】 coin change：给你 k 种面值的硬币，面值分别为 c1, c2 … ck，每种硬币的数量无限，再给一个总金额 amount，问你最少需要几枚硬币凑出这个金额

dp 数组的定义：当目标金额为 i 时，至少需要 dp[i] 枚硬币凑出。

dp[i][j] 的定义如下：

（个人理解，若为dp[i]则在遍历每种金额的种类时，每个问题不是独立子问题，无法直接相加，所以需加上硬币面值这一状态）
【PS】该题base case很特别，是base case 为 dp[0][…] = 0， dp[…][0] = 1。因为如果不使用任何硬币面值，就无法凑出任何金额；如果凑出的目标金额为 0，那么“无为而治”就是唯一的一种凑法。

class Solution {
public:
int change(int amount, vector<int>& coins)
{
int type=coins.size();
//dp[i][j]表示前i种硬币可构成j面额的种数
int dp[type+1][amount+1];
memset(dp,0,sizeof(dp));
for(int m=0;m<=amount;m++)
dp[0][m]=1;
for(int i=1;i<=coins.size();i++)
{
for(int j=1;j<=amount;j++)
{
if(coins[i-1]>j)
dp[i][j]=dp[i-1][j];
else
{
dp[i][j]=dp[i-1][j]+dp[i][j-coins[i-1]];
}
}
}
return dp[type][amount];
}
};

• 0
点赞
• 0
评论
• 0
收藏
• 一键三连
• 扫一扫，分享海报

03-24 495
01-30 21

11-12 316
03-28 179
03-08 124
03-22 127
08-10 1494
11-21 327
08-28 67