1、0-1背包问题
https://www.cnblogs.com/lfeng1205/p/5981198.html
2、动态规划之背包问题(一):01背包问题
https://blog.csdn.net/siyu1993/article/details/52836063
3、动态规划之背包问题(二):完全背包问题
https://blog.csdn.net/siyu1993/article/details/52858940
92.Backpack
Given n items with size Ai, an integer m denotes the size of a backpack. How full you can fill this backpack?
Example
If we have 4 items with size [2, 3, 5, 7], the backpack size is 11, we can select [2, 3, 5], so that the max size we can fill this backpack is 10. If the backpack size is 12. we can select [2, 3, 7] so that we can fulfill the backpack.
You function should return the max size we can fill in the given backpack.
Challenge
O(n x m) time and O(m) memory.
O(n x m) memory is also acceptable if you do not know how to optimize memory.
Notice
You can not divide any item into small pieces.
public class Solution {
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
public int backPack(int m, int[] A) {
// write your code here
int n=A.length;
int []result=new int [m+1];
//分清i的大小,i如果是[1,n]要比较的就是j与A[i-1],而且要注意有等号
for (int i=1;i<=n ;i++ ){
for(int j=m;j>0;j--){
if(j>=A[i-1]){
result[j]=Math.max(result[j],result[j-A[i-1]]+A[i-1]);
}
}
}
return result[m];
}
}
4、139. Word Break
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
Note:
The same word in the dictionary may be reused multiple times in the segmentation.
You may assume the dictionary does not contain duplicate words.
Example 1:
Input: s = “leetcode”, wordDict = [“leet”, “code”]
Output: true
Explanation: Return true because “leetcode” can be segmented as “leet code”.
Example 2:
Input: s = “applepenapple”, wordDict = [“apple”, “pen”]
Output: true
Explanation: Return true because “applepenapple” can be segmented as “apple pen apple”.
Note that you are allowed to reuse a dictionary word.
Example 3:
Input: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
Output: false
设dp[i]为前i个字符是否可以切割。
一个字符串S,它的长度为len,如果S能够被“字典集合”(dict)中的单词拼接而成,那么所要满足的条件为:
dp[j] && dict.contains(s.substring(j, i))
/*
|T| | | | | | | | |
0 1 2 3 4 5 6 7 8
i = 1
j = o sub = l
i = 2
j = 0 sub = le
j = 1 sub = e
i = 3
j = 0 sub = lee
j = 1 sub = ee
j = 2 sub = e
i = 4
j = 0 sub = leet && T[0] and then break, no need to check for rest
|T | | | |T| | | | |
0 1 2 3 4 5 6 7 8
i = 5
j = 0 sub = leetc
j = 1 sub = eetc
j = 2 sub = etc
j = 3 sub = tc
j = 4 sub = c
i = 6
j = 0 sub = leetco
j = 1 sub = eetco
j = 2 sub = etco
j = 3 sub = tco
j = 4 sub = co
j = 5 sub = o
i = 7
j = 0 sub = leetcod
j = 1 sub = eetcod
j = 2 sub = etcod
j = 3 sub = tcod
j = 4 sub = cod
j = 5 sub = od
j = 6 sub = d
i = 8
j = 0 sub = leetcode
j = 1 sub = eetcode
j = 2 sub = etcode
j = 3 sub = tcode
j = 4 sub = code && T[4] and then break
|T| | | |T| | | | T|
0 1 2 3 4 5 6 7 8
*/
public boolean wordBreak(String s, List<String> wordDict) {
int len=s.length();
boolean[] dp=new boolean[len+1];
dp[0]=true;
for(int i=1;i<=len;i++){
for(int j=0;j<i;j++){
if(dp[j]&&wordDict.contains(s.substring(j,i))){
dp[i]=true;
break;
}
}
}
return dp[len];
}