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 }
View Code

 

posted @ 2016-05-30 16:17  晴歌。  阅读(208)  评论(0编辑  收藏  举报