动态规划NC21313

知识总结:
虽然第i个数要不大于前i-1个数的均值,但不能只存前i-1个数的均值。
因为在进行多次整除的过程中会有数漏掉

#include<stdio.h>
#include<string.h>
int main(){
	//获取输入内容 
	int n;
	int ini[41];
	 int mod=1e9+7;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&ini[i]);
				//test:for(int i=1;i<=n;i++) printf("%d",ini[i]); 
	
	
	//创建动态规划所用的2个3维数组,简化使用设为一个4维数组
	int dp[2][41][1601][2];
	memset(dp,0,sizeof(dp));
	int lastflag;
	//根据第一个数进行初始化
	 if(ini[1]==-1){
	 		for(int j=0;j<41;j++){
	 			dp[0][j][j][1]=1;
	 		}
	 	}
	 	else{
	 		int d=ini[1];
	 		dp[0][d][d][1]=1;
	 	}
	 			//test:
				 	/*
					  for(int i=0;i<41;i++){
					  	for(int j=0;j<41;j++){
					  		printf("%d ",dp[0][i][j][0]);
					  	}
					  	printf("\n");
					  }
				 	*/
	 	
	 	//从输入数组的第二个开始遍历
		 for(int i=2;i<=n;i++){
		 	//第一次dp【0】-》dp【1】,之后dp【1】-》dp[0] 
		 	int flag1=i%2;
		 	int flag2=(i+1)%2;
		 	lastflag=flag2;
		 	memset(dp[flag2],0,sizeof(dp[flag2]));
		 	//-1
		 	if(ini[i]==-1){
		 		for(int j=0;j<41;j++){
		 			for(int k=0;k<1601;k++){
		 				int ad = k/(i-1);
		 				for(int torf=0;torf<2;torf++){
		 					if(dp[flag1][j][k][torf]==0) continue;
		 					
		 						for(int nownum=j;nownum<=ad;nownum++){

		 				
		 							dp[flag2][nownum][k+nownum][1]=(dp[flag2][nownum][k+nownum][1]+dp[flag1][j][k][torf])%mod;
		 						}
		 					if(torf==1){
		 						for(int nownum=0;nownum<j;nownum++){
		 					
		 							dp[flag2][nownum][k+nownum][0]=(dp[flag2][nownum][k+nownum][0]+dp[flag1][j][k][torf])%mod;
		 						}
		 					}
		 				}
		 			}
		 		}
		 	}//-1test 
		 	/*
			 for(int i=0;i<41;i++){
					  	for(int j=0;j<41;j++){
					  		printf("%d ",dp[flag2][i][j][1]);
					  	}
					  	printf("\n");
					  }
			 */
			 
			 
		 	//不是-1 
		 	else{
		 		int d=ini[i];
		 			for(int j=0;j<41;j++){
		 			for(int k=0;k<1601;k++){
		 				int ad = k/(i-1);
		 				for(int torf=0;torf<2;torf++){
		 					if(dp[flag1][j][k][torf]==0) continue;
		 					
		 						for(int nownum=j;nownum<=ad;nownum++){
		 							if(nownum!=d) continue;
		 							
		 				
		 							dp[flag2][nownum][k+nownum][1]=(dp[flag2][nownum][k+nownum][1]+dp[flag1][j][k][torf])%mod;
		 						}
		 					if(torf==1){
		 						for(int nownum=0;nownum<j;nownum++){
		 							if(nownum!=d) continue;
		 						
		 					
		 							dp[flag2][nownum][k+nownum][0]=(dp[flag2][nownum][k+nownum][0]+dp[flag1][j][k][torf])%mod;
		 						}
		 					}
		 				}
		 			}
		 		}
		 	}
		 	//-1test 
		 	
		
		 } 
		
			int num=0;
		 	for(int j=0;j<41;j++){
		 		for(int k=0;k<1601;k++){
		 			for(int l=0;l<2;l++){
		 			num=(num+dp[lastflag][j][k][l])%mod;	
		 			}
		 		}
		 		}
			 printf("%d",num);
		 	
	 }

个人总结:写的过程中效率太低,解决办法就是模块化的去写,写完一部分测试一部分,闷头写到末尾再从头找错是最打击人的积极性的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值