划分数(有关计数类的DP)
1,发现你把这些看起来似乎很抽象的东西,转化成具体的话(比如带进去几个数字)就会很简单。这种对立的转换是不是也。。是一种什么。
2,也不一定要先看文字,可以先看代码再看文字。比如上次那个你要是光看文字我估计你肯定看不懂。
3,这个东西有点像套东西,我正着套,我反着套,我从中间套。
#include<iostream> using namespace std; int n,m,M; int dp[1005][1005]; int main(){ cin>>n>>m>>M; dp[0][0]=1; for(int i=1;i<=m;i++) { for(int j=0;j<=n;j++) { if(j-i>=0) { dp[i][j]=(dp[i-1][j]+dp[i][j-i])%M; } else { dp[i][j]=dp[i-1][j]; } } } cout<<dp[m][n]<<endl; }
4,害,淦。你可以分0,但是你不可以分成0份。
要我说,模拟代码才是正道。
模拟的时候一定要注意同时要思考。
划分说的是不超过那个数的。
模拟一遍我搞的懂了,但是感觉深刻的思想还是没懂。
5,还行开始费大费小。
这个道理我目前不是很能给你讲清了
递推式我讲不出来一二三啊。。
我需要一个证明,关乎为什么j的i划分就等于j-i的i划分加上j的i-1划分。
我是实在也费不出来啥。。。
费大不行
费小,
#include<iostream> using namespace std; int n,m,M,dp[1005][1005]; int main(){ cin>>n>>m>>M; dp[0][0]=1; for(int i=1;i<=m;i++) { for(int j=0;j<=n;j++) { if(j-i<0) { dp[i][j]=dp[i-1][j]; } else { dp[i][j]=(dp[i-1][j]+dp[i][j-i])%M; } } } cout<<dp[m][n]<<endl; }