题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=1600
题解:
很明显的一道dp题,用dp[i][k]表示前i段木板分割成长度为k段的方法数,如果不考虑四边形的话,转移方程很简单就不细说了,但是如何判断它满足一个四边形呢,看了hzwer的说明才知道四边形三边之和必须大于第四边,可以转化为每一条边都必须小于总边长的一半,别吐槽这是小学知识或其他什么东西,蒟蒻现在才发现(ORZ),然后知道了这个定理后就比较好做了,状态转移的时候条件改变一下就行了:
int len=边长的一半;
dp[i][k]+=dp[j][k-1];(i-j<len)
附代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
int n;
long long dp[2505][5];
int main()
{
scanf("%d",&n);
dp[0][0]=1;
int len=(n+1)/2;
for (int k=1;k<=4;k++)
for (int i=1;i<=n;i++)
{
for (int j=0;j<i;j++)
if (i-j<len)
dp[i][k]+=dp[j][k-1];
}
//for (int i=1;i<=n;i++)
//cout<<dp[i][1]<<' '<<dp[i][2]<<' '<<dp[i][3]<<' '<<dp[i][4]<<endl;
printf("%lld\n",dp[n][4]);
}