Dynamic Planning Learning Series-divide DP (2) and Plan dp
The second question of Partitioned DP, wikioi 1039, is different from the biggest idea of the product of the first question.
Question requirements:
Divide a number into several parts and ask the total number of methods.
Truth-solving ideas:
In fact, it is a bit like some of the questions of Primary School Olympics. Let's look at an example:
7 is divided into three parts and there are four methods:
1, 1, 5; 1, 2, 4; 1, 3; 2, 3.
What do we think when we think about the problem? Obviously, starting from 1, 1 is Part 1, and then the remaining part is divided into two parts. We still consider starting from 1, 1 is part 2, and 5 is Part 2; in the same case, part 1 is 2, Part 2 is 4, and Part 2 is 3, and Part 2 is 3, because each part cannot be smaller than the previous one (avoid duplication ), therefore, Part 1 is considered as Part 2, and Part 2 is considered as Part 2. Similarly, it starts from Part 2 as Part 2. Therefore, only Part 2 is considered as this case.
The idea of the above human brain is a bit like search, which is why I like deep search algorithms.
But now we don't want to use search, but dynamic planning. What should we do?
Famous saying of a Daniel:Dynamic Planning = memory-based search
We also know that dynamic planning uses the previous state to launch the current state, so we can consider it as follows: take part 1st separately, consider all the situations in part 1 and all the corresponding elimination situations where the first part is divided into Part 1, so there areState transition equation:
Dp [I] [j] = Σ dp [I-k] [J-1] (1 <= k <= j/I)
You can also simplify it, Because dp [I-1] [J-1] = Σ dp [i-k-1] [J-1]:
Dp [I] [j] = dp [I-1] + dp [I-j] [j]
This formula can be understood as follows: first consider that Part 1 is 1, and the remaining part 1st must be greater than 1. Therefore, it is okay to reduce each part by 1. This value is also known to us!
Code:
#include <bits/stdc++.h>using namespace std;int n,m,dp[205][10];int main(){ scanf("%d %d",&n,&m); dp[0][0]=1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(j<=i) dp[i][j]=dp[i-j][j]+dp[i-1][j-1]; } } printf("%d\n",dp[n][m]); return 0;}
Summary:
1. Although programming is from the machine's point of view, it is also good to run with the human brain occasionally;
2. Dynamic Planning is a memory-based deep search;
3. Remember not to repeat it!