[Usaco2008 Oct]建造栅栏 DP

勤奋的Farmer John想要建造一个四面的栅栏来关住牛们。他有一块长为n(4<=n<=2500)的木板,他想把这块本板切成4块。 这四块小木板可以是任何一个长度只要Farmer John能够把它们围成一个合理的四边形。他能够切出多少种不同的合理方案。 注意: *只要大木板的切割点不同就当成是不同的方案(像全排列那样),不要担心另外的特殊情况,go ahead。 *栅栏的面积要大于0. *输出保证答案在longint范围内。 *整块木板都要用完。



构成四边形的条件是三边和大于第四边。

也就隐含了一个条件,任意一条边的长度都是小于边长之和的一半

然后就可以得到一个类似于背包的DP

dp[i, j]代表使用了i条边构成边长之和为j的方案数

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define lch(x) x<<1
#define rch(x) x<<1|1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MAXN 2555
#define MAXM 555
#define INF 1000000007
using namespace std;
int n;
int dp[5][MAXN];
int main()
{
    scanf("%d", &n);
    dp[0][0] = 1;
    int up = (n + 1) / 2 - 1;
    for(int k = 1; k <= 4; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= up; j++)
                if(i >= j) dp[k][i] += dp[k - 1][i - j];
    printf("%d\n", dp[4][n]);
    return 0;
}


你可能感兴趣的:([Usaco2008 Oct]建造栅栏 DP)