#include
#include
//挑战程序设计竞赛(第2版) 2.3.3 有关计数问题的DP
//感觉就像倒过来找
//错误 0分 修改
//错误 0分
//错误 20
//30
//-879048156
//第一个动态规划的程序
//错误 40
//60
//-609189446
int main()
{
int NUM;
scanf("%d",&NUM);
long long dp[NUM+1][1<<3];//+20 long long 防溢出
memset(dp,0,sizeof(dp));
int i;
int j;//flag0flag1flag3
dp[2][1]=1;//23 001
dp[2][0]=1;//22 000
dp[2][4]=1;//20 100
dp[3][5]=2;//203 230 101
dp[3][6]=1;//201 110
for(i=0;i<=NUM;i++)//+20分
{
for(j=0;j<1<<3;j++)
{
if((i>=4)&&(j==7))//111
{
dp[i][7]=(dp[i-1][7]*2//下一位只能选择1或3
+dp[i-1][6]//下一位只能选择3 110
+dp[i-1][5])%1000000007;//下一位只能选择1 101//%1000000007 +60
}
if((i>=3)&&(j==6)&&(i=3)&&(j==5)&&(i=2)&&(j==4)&&(i=2)&&(j==1)&&(i
下面是同一个问题的另一个程序。运行超时,20分。
#include
//一位一位的算
// 运行超时 20
//已经剪枝了
//挑战程序设计竞赛(第2版) 2.3.3 有关计数问题的DP
//感觉就像倒过来找
void DFS(int& total,int NUM,int n,int flag0,int flag1,int flag3)//减少到两个变量 n和flag0flag1flag3 P54从记忆搜索出发推导出递推式
{
//printf("%d %d %d %d %d\n",n,flag0,flag1,flag3,total);
if((n==NUM)&&(flag0==1)&&(flag1==1)&&(flag3==1))
{
total++;
}
if(n==NUM)
{
return;
}
int _flag0=flag0;
int _flag1=flag1;
int _flag3=flag3;
if((flag1==0)&&(flag3==1))//1没有出现过3出现过可以选择0,1,3
{
flag0=1;//这一位选择0
DFS(total,NUM,n+1,flag0,flag1,flag3);
flag0=_flag0;
flag1=_flag1;
flag3=_flag3;
flag1=1;//选择1
DFS(total,NUM,n+1,flag0,flag1,flag3);
flag0=_flag0;
flag1=_flag1;
flag3=_flag3;
flag3=1;//选择3
DFS(total,NUM,n+1,flag0,flag1,flag3);
}else if((flag1==1)&&(flag3==0))//1出现过3没有出现过可以选择2,1, 3
{
//flag2=1;//这一位选择2
DFS(total,NUM,n+1,flag0,flag1,flag3);
flag0=_flag0;
flag1=_flag1;
flag3=_flag3;
flag1=1;//选择1
DFS(total,NUM,n+1,flag0,flag1,flag3);
flag0=_flag0;
flag1=_flag1;
flag3=_flag3;
flag3=1;//选择3
DFS(total,NUM,n+1,flag0,flag1,flag3);
}else if((flag1==0)&&(flag3==0))//1没出现过3没出现过可以选择 0,1,2, 3
{
//选择0
flag0=1;
DFS(total,NUM,n+1,flag0,flag1,flag3);
flag0=_flag0;
flag1=_flag1;
flag3=_flag3;
flag1=1;//选择1
DFS(total,NUM,n+1,flag0,flag1,flag3);
flag0=_flag0;
flag1=_flag1;
flag3=_flag3;
//选择2
DFS(total,NUM,n+1,flag0,flag1,flag3);
flag0=_flag0;
flag1=_flag1;
flag3=_flag3;
flag3=1;//选择3
DFS(total,NUM,n+1,flag0,flag1,flag3);
}else if((flag1==1)&&(flag3==1))//1出现过3出现过可以选择1, 3
{
flag1=1;//选择1
DFS(total,NUM,n+1,flag0,flag1,flag3);
flag0=_flag0;
flag1=_flag1;
flag3=_flag3;
flag3=1;//选择3
DFS(total,NUM,n+1,flag0,flag1,flag3);
}
}
int main()
{
int NUM;
scanf("%d",&NUM);
NUM=NUM-1;//第一位一定是2
int total=0;
DFS(total,NUM,0,0,0,0);
printf("%d",total%1000000007);
return 0;
}