BZOJ_1600_[Usaco2008_Oct]_建造栅栏_(动态规划)
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1600
将长度为n的线段分成4段,长度为整数,围成面积>0的四边形,求方案数.
分析
首先对于四边形的四条边a,b,c,d有:
a<b+c+d.
我们考虑搜索的想法,就是在剩余长度和(n+1)/2-1,这两者的最小值以下枚举当前边的长度后,再到下一条边,剩余长度要减去当前选择的长度,这样就会有重叠子问题,可以记忆化搜索.当然倒过来就是dp了.
dp[i][j]表示选完了第i条边后用去j长度的方案数,则有:
dp[i][j]=sum{dp[i-1][j-k](1<=k<=min((n+1)/2-1,j))}.
注意:
1.初始值dp[0][0]=1.
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=2500+5; 5 int n; 6 int dp[5][maxn]; 7 int main(){ 8 scanf("%d",&n); 9 int mid=(n+1)/2-1; 10 dp[0][0]=1; 11 for(int i=1;i<=4;i++)for(int j=1;j<=n;j++){ 12 int K=min(j,mid); 13 for(int k=1;k<=K;k++) dp[i][j]+=dp[i-1][j-k]; 14 } 15 printf("%d\n",dp[4][n]); 16 return 0; 17 }