您的位置:首页 > 其它

hdu 2510 符号三角形

2016-10-23 14:22 288 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2510

题目描述:

Problem Description

符号三角形的 第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“,2个异 号下面是”-“ 。计算有多少个不同的符号三角形,使其所含”+“ 和”-“ 的个数相同 。 n=7时的1个符号三角形如下:

+ + - + - + + 

+ - - - - + 

- + + + - 

- + + - 

- + - 

- - 

+

 

Input

每行1个正整数n <=24,n=0退出.

 

Output

n和符号三角形的个数. 

 

Sample Input

15
16
19
20
0

 

Sample Output

15 1896
16 5160
19 32757
20 59984

题目分析:

dfs,易知每一个符号三角形都是由第一行所决定,当第一行确定了下来以后那么后面的n-1行也就由题目中的规则唯一的确定了下来,这个道理相信许多人都知道,关键是如何去实现它,在这里我也困扰了许久,最后突然想到我们也可以通过倒着做,即先确定最后一行的哪一个数,这里只要考虑两种情况,要么是‘+’要么是'-',然后呢,我们再推出他的上面一行,同样,由于下面一行已经确定了,所以在这里我们只要知道这一行的第一个符号是什么,那么这一行的所有符号也就唯一确定了下来,在这里我们也就只需要考虑两种情况,要么'+'要么'-',所以也就是说,每一行都只要考虑第一个符号,大大的减少复杂性

第一发深搜超时,用的打表暴力AC:

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long

/*const int maxn=25;
int n;
ll anss;
int map[maxn][maxn];
ll ans[maxn];

void dfs(int m,int z,int f)//把数字三角形倒过来看,一共就两种
{
if(z>(n*(n+1)/4)||f>(n*(n+1)/4))
return;
if(m==n+1)
{
if(z==f)
{
anss++;
}
return;
}

if(m==1)
{
map[1][1]=1;
dfs(m+1,z+1,f);
map[1][1]=0;
dfs(m+1,z,f+1);
}
else
{
int num_neg=0,num_pos=0;
//首位是0
//1是+,0是-
map[m][1]=0;
num_neg++;
for(int i=2;i<=m;i++)
{
if(map[m-1][i-1]==1)
{
map[m][i]=map[m][i-1];
if(map[m][i])
num_pos++;
else
num_neg++;
}
else
{
if(map[m][i-1]==1)
{
map[m][i]=0;
num_neg++;
}
else
{
map[m][i]=1;
num_pos++;
}
}
}
dfs(m+1,z+num_pos,f+num_neg);

//首位是1
num_pos=0;
num_neg=0;
map[m][1]=1;
num_pos++;
for(int i=2;i<=m;i++)
{
if(map[m-1][i-1])
{
map[m][i]=map[m][i-1];
if(map[m][i])
num_pos++;
else
num_neg++;
}
else
{
if(map[m][i-1])
{
map[m][i]=0;
num_neg++;
}
else
{
map[m][i]=1;
num_pos++;
}
}
}
dfs(m+1,z+num_pos,f+num_neg);
}
}*/

int main()
{
/*for(int i=1;i<=24;i++)
{
n=i;
anss=0;
memset(map,0,sizeof(map));
dfs(1,0,0);
ans[i]=anss;
printf("%d ",anss);
}*/
ll v[]={0,0,0,4,6,0,0,12,40,0,0,171,410,0,0,1896,5160,0,0,32757,59984,0,0,431095,822229};
while(scanf("%d",&n)!=0&&n!=0)
{
//memset(map,0,sizeof(map));
//dfs(1,0,0);
printf("%d %lld\n",n,v
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: