int fib(int n) {
if(n==1) return 1;
int aa[40];
aa[0]=0;aa[1]=1;
for(int i=2;i<=n;i++){
aa[i]=aa[i-1]+aa[i-2];
}
return aa[n];
}
int climbStairs(int n) {
int f[50];
f[1]=1;
f[2]=2;
for(int i=3;i<=n;i++){
f[i]=f[i-1]+f[i-2];
}
return f[n];
}
int minCostClimbingStairs(vector<int>& cost) {
int f[1010];
f[0]=0;
f[1]=0;
for(int i=2;i<=cost.size();i++){
f[i]=min(f[i-1]+cost[i-1],f[i-2]+cost[i-2]);
}
return f[cost.size()];
}
二维做法
int uniquePaths(int m, int n) {
int a[m][n];
for(int i=0;i<m;i++) a[i][0]=1;
for(int i=0;i<n;i++) a[0][i]=1;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(i&&j) a[i][j]=a[i-1][j]+a[i][j-1];
}
}
// for(int i=0;i<m;i++){
// for(int j=0;j<n;j++){
// cout<<a[i][j]<<" ";
// }cout<<endl;
// }
return a[m-1][n-1];
}
一维做法
int uniquePaths(int m, int n) {
int a[n];
for(int i=0;i<n;i++) a[i]=1;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(i&&j) a[j]=a[j]+a[j-1];
}
}
return a[n-1];
}
二维做法
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if(obstacleGrid[0][0]==1) return 0;
int n=obstacleGrid.size(),m=obstacleGrid[0].size();
int f[n][m];
memset(f,0,sizeof(f));
for(int i=0;i<n;i++){
if(obstacleGrid[i][0]==1) break;
f[i][0]=1;
}
for(int i=0;i<m;i++){
if(obstacleGrid[0][i]==1) break;
f[0][i]=1;
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(obstacleGrid[i][j]==1) f[i][j]=0;
if(obstacleGrid[i][j]!=1&&i&&j) f[i][j]=f[i-1][j]+f[i][j-1];
}
}
return f[n-1][m-1];
}
一维做法
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if(obstacleGrid[0][0]==1) return 0;
int n=obstacleGrid.size(),m=obstacleGrid[0].size();
int f[m];
memset(f,0,sizeof(f));
for(int i=0;i<m;i++){
if(obstacleGrid[0][i]==1) break;
f[i]=1;
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(obstacleGrid[i][j]==1) f[j]=0;
if(obstacleGrid[i][j]!=1&&i&&j) f[j]=f[j]+f[j-1];
}
}
return f[m-1];
}
数学方法:3尽可能多2最多两个。
int integerBreak(int n) {
if(n<=3) return n-1;
int p=1;
while(n>=5) n-=3,p*=3;
return p*n;
}
dp:
int integerBreak(int n) {
int f[100];
memset(f,0,sizeof(f));
f[1]=1;
f[2]=1;
f[3]=2;
for(int i=3;i<=n;i++){
for(int j=2;j<=i;j++){
f[i]=max(f[i],max((i-j)*j,f[i-j]*j));
}
}
return f[n];
}
递推方程:dp[j]=sum(f[i-j-1]*f[j])
int numTrees(int n) {
int f[n+10];
memset(f,0,sizeof(f));
f[0]=1;f[1]=1;f[2]=2,f[3]=5;
for(int i=4;i<=n;i++){
for(int j=0;j<i;j++){
f[i]+=f[i-j-1]*f[j];
}
}
return f[n];
}
递推方程:dp[i][j]=max(dp[i-1][j],dp[i][j-nums[i]+nums[i]]
bool canPartition(vector<int>& nums) {
int sum=0;
for(int i=0;i<nums.size();i++) sum+=nums[i];
if(sum%2==1) return false;
int f[sum/2+1];
memset(f,0,sizeof(f));
for(int i=0;i<nums.size();i++) {
for(int j=sum/2;j>=nums[i];j--){
f[j]=max(f[j],f[j-nums[i]]+nums[i]);
}
}
if(f[sum/2]==sum/2) return 1;
else return 0;
}
递推方程:dp[i][j]=max(dp[i-1][j],dp[i][j-stones[i]+stones[i]]
int lastStoneWeightII(vector<int>& stones) {
int sum=0;
for(int i=0;i<stones.size();i++) sum+=stones[i];
int tar=sum/2;
int f[tar+10];
memset(f,0,sizeof(f));
for(int i=0;i<stones.size();i++){
for(int j=tar;j>=stones[i];j--){
f[j]=max(f[j],f[j-stones[i]]+stones[i]);
}
}
return sum-f[tar]-f[tar];
}
递推方程:dp[i][j]=dp[i-1][j]+dp[i][j-nums[i]];
int res=0;int aa=0;
int findTargetSumWays(vector<int>& nums, int target) {
int sum=0;
for(int i=0;i<nums.size();i++) sum+=nums[i];
if((target+sum)%2==1||abs(target)>sum) return 0;
int xx=(target+sum)/2;
vector<int>f(xx+1,0);
f[0]=1;
for(int i=0;i<nums.size();i++)
for(int j=xx;j>=nums[i];j--) f[j]+=f[j-nums[i]];
return f[xx];
}
递推方程:dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-zero][k-one]+1)
三维
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> nums;
for(int i=0;i<strs.size();i++){
int one=0,zero=0;
vector<int> temp;
for(int j=0;j<strs[i].size();j++){
if(strs[i][j]=='1') one++;
else zero++;
}
temp.push_back(zero);temp.push_back(one);
nums.push_back(temp);
}
vector<int> xx;
xx.push_back(0);xx.push_back(0);
nums.insert(nums.begin(),xx);
int dp[nums.size()+1][m+1][n+1];
memset(dp,0,sizeof(dp));
for(int i=1;i<nums.size();i++){
int zero=nums[i][0],one=nums[i][1];
for(int j=0;j<=m;j++){
for(int k=0;k<=n;k++){
dp[i][j][k]=dp[i-1][j][k];
if(k) dp[i][j][k]=max(dp[i][j][k],dp[i][j][k-1]);
if(j) dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k]);
if(j>=zero&&k>=one)
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-zero][k-one]+1);
}
}
}
return dp[nums.size()-1][m][n];
}
二维优化:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> nums;
for(int i=0;i<strs.size();i++){
int one=0,zero=0;
vector<int> temp;
for(int j=0;j<strs[i].size();j++){
if(strs[i][j]=='1') one++;
else zero++;
}
temp.push_back(zero);temp.push_back(one);
nums.push_back(temp);
}
vector<int> xx;
xx.push_back(0);xx.push_back(0);
nums.insert(nums.begin(),xx);
int dp[m+1][n+1];
memset(dp,0,sizeof(dp));
for(int i=1;i<nums.size();i++){
int zero=nums[i][0],one=nums[i][1];
for(int j=m;j>=zero;j--){
for(int k=n;k>=one;k--){
if(k) dp[j][k]=max(dp[j][k],dp[j][k-1]);
if(j) dp[j][k]=max(dp[j][k],dp[j-1][k]);
if(j>=zero&&k>=one)
dp[j][k]=max(dp[j][k],dp[j-zero][k-one]+1);
}
}
}
return dp[m][n];
}
递推方程:dp[i][j]+=dp[i-1][j-nums[i]*k]//k是个数
二维写法
int change(int amount, vector<int>& nums) {
nums.insert(nums.begin(),0);
int f[nums.size()+1][amount+1];
memset(f,0,sizeof(f));
f[0][0]=1;
for(int i=1;i<nums.size();i++){
for(int j=0;j<=amount;j++){
// f[i][j]=f[i-1][j];
for(int k=0;k*nums[i]<=j;k++){
f[i][j]+=f[i-1][j-nums[i]*k];
}
}
}
return f[nums.size()-1][amount];
}
一维写法
int change(int amount, vector<int>& nums) {
nums.insert(nums.begin(),0);
int f[amount+1];
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1;i<nums.size();i++){
for(int j=amount;j>=0;j--){
for(int k=1;k*nums[i]<=j;k++){
f[j]+=f[j-nums[i]*k];
}
}
}
return f[amount];
}
int combinationSum4(vector<int>& nums, int target) {
nums.insert(nums.begin(),0);
int f[target+1];
memset(f,0,sizeof(f));
f[0]=1;
for(int i=0;i<=target;i++){
for(int j=1;j<nums.size();j++){
if(i>=nums[j]&&f[i]<INT_MAX-f[i-nums[j]]) f[i]+=f[i-nums[j]];
}
}
return f[target];
}
int coinChange(vector<int>& coins, int amount) {
int f[amount+1];
memset(f,0x3f,sizeof(f));
f[0]=0;
coins.insert(coins.begin(),0);
for(int i=1;i<coins.size();i++){
for(int j=coins[i];j<=amount;j++){
if(j>=coins[i]) f[j]=min(f[j],f[j-coins[i]]+1);
}
}
if(f[amount]>=0x3f3f3f3f/2) return -1;
return f[amount];
}
int numSquares(int n) {
vector<int> nums;
for(int i=0;i*i<=n;i++) nums.push_back(i*i);
int f[n+1];
memset(f,0x3f,sizeof(f));
f[0]=0;
for(int i=1;i<nums.size();i++){
for(int j=nums[i];j<=n;j++){
if(j>=nums[i]) f[j]=min(f[j],f[j-nums[i]]+1);
}
}
return f[n];
}