CSP考试 2013年12月第4题 有趣的数 C++实现

CSP考试 2013年12月第4题 有趣的数 C++实现_第1张图片

#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; 
}


你可能感兴趣的:(CSP)