【cdoj 1323】柱爷的下凡 dp打表预处理

本文分享了一种通过打表预处理提升程序效率的方法,并提供了详细的代码实现。针对特定问题,利用动态规划算法进行优化,使得查询答案的时间复杂度降至O(1),显著提升了程序性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感觉这道题还是蛮有意义的,因为有时候打表预处理真的能够提升很多的时间。但是想要打表好一点还是不容易啊,比如说我看另外一份题解,光打表就我跑了3分钟都还没有跑出来,后来实在是没有耐心了,自己写了一份代码,打表就用了几秒,我也是心累。

看到数据范围,虽然说只有200,但是如果直接在交上去的代码中直接跑dp绝对会超时,而我们注意到对于每一个题目的答案都是唯一的,不会改变,所以可以先预处理出答案然后直接O(1)查询水掉,之所以重点是打表,下面给出打表代码和标程(有注释)

打表代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int ans2[205],ans3[205],dp[205];

int main(){
	freopen("柱爷的下凡.cpp","w",stdout);
	int sum,last;
	ans2[1]=2;ans3[1]=3;
	ans2[2]=2;ans3[2]=3;
	ans2[3]=2;ans3[3]=3;
	for(int i=4;i<=201;i++){
		last=1e9;
		for(int j=2;j<i;j++){//第二枚硬币 
			for(int k=j+1;k<=i;k++){//第三枚硬币 
				sum=0;//总共用了多少硬币 
				dp[0]=0;//dp表示使用当前两种硬币凑出i的币值最少需要多少枚硬币 
				for(int l=1;l<=i;l++){ //用前面的算出来的更新dp 
					if(l>=k)dp[l]=min(min(dp[l-k],dp[l-j]),dp[l-1])+1;//可以用第三种硬币
					else if(l>=j)dp[l]=min(dp[l-j],dp[l-1])+1;//可用第二种 
					else dp[l]=dp[l-1]+1;//只能用第一种 
				}
				for(int l=1;l<=i;l++)sum+=dp[l];//总共用了多少硬币 
				if(sum<last){//更新最终答案 
					last=sum;
					ans2[i]=j;ans3[i]=k;
				}
			}
			
		}
	}
	printf("#include<cstdio>\n\n\n");
	printf("int ans2[210],ans3[210];\n");
	printf("int main(){\n");
	for(int i=1;i<=201;i++)printf("ans2[%d]=%d , ans3[%d]=%d;\n",i,ans2[i],i,ans3[i]);
	
	printf("return 0;\n}");
}


标程代码(200+自信水过 啦啦啦):

#include<cstdio>
int ans2[210],ans3[210];
int n,T;


int main(){
ans2[1]=2 , ans3[1]=3;
ans2[2]=2 , ans3[2]=3;
ans2[3]=2 , ans3[3]=3;
ans2[4]=2 , ans3[4]=3;
ans2[5]=2 , ans3[5]=3;
ans2[6]=2 , ans3[6]=3;
ans2[7]=2 , ans3[7]=5;
ans2[8]=3 , ans3[8]=4;
ans2[9]=3 , ans3[9]=4;
ans2[10]=2 , ans3[10]=5;
ans2[11]=2 , ans3[11]=5;
ans2[12]=4 , ans3[12]=6;
ans2[13]=4 , ans3[13]=6;
ans2[14]=4 , ans3[14]=6;
ans2[15]=3 , ans3[15]=7;
ans2[16]=4 , ans3[16]=6;
ans2[17]=3 , ans3[17]=7;
ans2[18]=4 , ans3[18]=6;
ans2[19]=3 , ans3[19]=8;
ans2[20]=3 , ans3[20]=8;
ans2[21]=5 , ans3[21]=7;
ans2[22]=4 , ans3[22]=9;
ans2[23]=4 , ans3[23]=9;
ans2[24]=5 , ans3[24]=8;
ans2[25]=5 , ans3[25]=8;
ans2[26]=5 , ans3[26]=8;
ans2[27]=5 , ans3[27]=8;
ans2[28]=4 , ans3[28]=9;
ans2[29]=5 , ans3[29]=8;
ans2[30]=5 , ans3[30]=8;
ans2[31]=4 , ans3[31]=9;
ans2[32]=5 , ans3[32]=8;
ans2[33]=5 , ans3[33]=8;
ans2[34]=7 , ans3[34]=11;
ans2[35]=7 , ans3[35]=11;
ans2[36]=7 , ans3[36]=11;
ans2[37]=5 , ans3[37]=12;
ans2[38]=5 , ans3[38]=12;
ans2[39]=5 , ans3[39]=12;
ans2[40]=7 , ans3[40]=11;
ans2[41]=5 , ans3[41]=12;
ans2[42]=5 , ans3[42]=12;
ans2[43]=5 , ans3[43]=12;
ans2[44]=7 , ans3[44]=11;
ans2[45]=7 , ans3[45]=11;
ans2[46]=7 , ans3[46]=11;
ans2[47]=7 , ans3[47]=11;
ans2[48]=6 , ans3[48]=14;
ans2[49]=6 , ans3[49]=14;
ans2[50]=6 , ans3[50]=14;
ans2[51]=6 , ans3[51]=14;
ans2[52]=8 , ans3[52]=13;
ans2[53]=8 , ans3[53]=13;
ans2[54]=8 , ans3[54]=13;
ans2[55]=8 , ans3[55]=13;
ans2[56]=8 , ans3[56]=13;
ans2[57]=6 , ans3[57]=14;
ans2[58]=6 , ans3[58]=14;
ans2[59]=6 , ans3[59]=14;
ans2[60]=8 , ans3[60]=13;
ans2[61]=8 , ans3[61]=13;
ans2[62]=6 , ans3[62]=14;
ans2[63]=6 , ans3[63]=14;
ans2[64]=6 , ans3[64]=14;
ans2[65]=8 , ans3[65]=13;
ans2[66]=8 , ans3[66]=13;
ans2[67]=8 , ans3[67]=13;
ans2[68]=8 , ans3[68]=13;
ans2[69]=7 , ans3[69]=17;
ans2[70]=7 , ans3[70]=17;
ans2[71]=7 , ans3[71]=17;
ans2[72]=7 , ans3[72]=17;
ans2[73]=7 , ans3[73]=17;
ans2[74]=9 , ans3[74]=14;
ans2[75]=7 , ans3[75]=17;
ans2[76]=7 , ans3[76]=17;
ans2[77]=7 , ans3[77]=17;
ans2[78]=7 , ans3[78]=17;
ans2[79]=7 , ans3[79]=17;
ans2[80]=10 , ans3[80]=16;
ans2[81]=10 , ans3[81]=16;
ans2[82]=10 , ans3[82]=16;
ans2[83]=10 , ans3[83]=16;
ans2[84]=8 , ans3[84]=19;
ans2[85]=8 , ans3[85]=19;
ans2[86]=8 , ans3[86]=19;
ans2[87]=8 , ans3[87]=19;
ans2[88]=6 , ans3[88]=20;
ans2[89]=10 , ans3[89]=17;
ans2[90]=11 , ans3[90]=15;
ans2[91]=11 , ans3[91]=15;
ans2[92]=11 , ans3[92]=15;
ans2[93]=11 , ans3[93]=15;
ans2[94]=11 , ans3[94]=18;
ans2[95]=11 , ans3[95]=18;
ans2[96]=12 , ans3[96]=19;
ans2[97]=12 , ans3[97]=19;
ans2[98]=12 , ans3[98]=19;
ans2[99]=12 , ans3[99]=19;
ans2[100]=12 , ans3[100]=19;
ans2[101]=12 , ans3[101]=19;
ans2[102]=12 , ans3[102]=19;
ans2[103]=12 , ans3[103]=19;
ans2[104]=12 , ans3[104]=19;
ans2[105]=12 , ans3[105]=19;
ans2[106]=12 , ans3[106]=19;
ans2[107]=12 , ans3[107]=19;
ans2[108]=12 , ans3[108]=19;
ans2[109]=12 , ans3[109]=19;
ans2[110]=12 , ans3[110]=19;
ans2[111]=13 , ans3[111]=18;
ans2[112]=12 , ans3[112]=19;
ans2[113]=12 , ans3[113]=19;
ans2[114]=12 , ans3[114]=19;
ans2[115]=12 , ans3[115]=19;
ans2[116]=12 , ans3[116]=19;
ans2[117]=12 , ans3[117]=19;
ans2[118]=12 , ans3[118]=19;
ans2[119]=12 , ans3[119]=19;
ans2[120]=12 , ans3[120]=19;
ans2[121]=12 , ans3[121]=19;
ans2[122]=12 , ans3[122]=19;
ans2[123]=7 , ans3[123]=23;
ans2[124]=7 , ans3[124]=23;
ans2[125]=8 , ans3[125]=27;
ans2[126]=8 , ans3[126]=27;
ans2[127]=8 , ans3[127]=27;
ans2[128]=9 , ans3[128]=23;
ans2[129]=9 , ans3[129]=23;
ans2[130]=9 , ans3[130]=23;
ans2[131]=9 , ans3[131]=30;
ans2[132]=9 , ans3[132]=30;
ans2[133]=14 , ans3[133]=22;
ans2[134]=14 , ans3[134]=22;
ans2[135]=10 , ans3[135]=26;
ans2[136]=14 , ans3[136]=22;
ans2[137]=8 , ans3[137]=27;
ans2[138]=8 , ans3[138]=27;
ans2[139]=14 , ans3[139]=22;
ans2[140]=8 , ans3[140]=27;
ans2[141]=8 , ans3[141]=27;
ans2[142]=10 , ans3[142]=26;
ans2[143]=8 , ans3[143]=27;
ans2[144]=8 , ans3[144]=27;
ans2[145]=8 , ans3[145]=27;
ans2[146]=8 , ans3[146]=27;
ans2[147]=8 , ans3[147]=27;
ans2[148]=8 , ans3[148]=27;
ans2[149]=8 , ans3[149]=27;
ans2[150]=8 , ans3[150]=27;
ans2[151]=8 , ans3[151]=27;
ans2[152]=8 , ans3[152]=27;
ans2[153]=9 , ans3[153]=30;
ans2[154]=9 , ans3[154]=30;
ans2[155]=9 , ans3[155]=30;
ans2[156]=9 , ans3[156]=30;
ans2[157]=9 , ans3[157]=30;
ans2[158]=9 , ans3[158]=30;
ans2[159]=9 , ans3[159]=30;
ans2[160]=9 , ans3[160]=30;
ans2[161]=9 , ans3[161]=30;
ans2[162]=9 , ans3[162]=30;
ans2[163]=9 , ans3[163]=30;
ans2[164]=9 , ans3[164]=30;
ans2[165]=9 , ans3[165]=30;
ans2[166]=9 , ans3[166]=30;
ans2[167]=9 , ans3[167]=30;
ans2[168]=9 , ans3[168]=30;
ans2[169]=9 , ans3[169]=30;
ans2[170]=9 , ans3[170]=30;
ans2[171]=9 , ans3[171]=30;
ans2[172]=12 , ans3[172]=31;
ans2[173]=12 , ans3[173]=31;
ans2[174]=12 , ans3[174]=31;
ans2[175]=12 , ans3[175]=31;
ans2[176]=10 , ans3[176]=34;
ans2[177]=10 , ans3[177]=34;
ans2[178]=10 , ans3[178]=34;
ans2[179]=10 , ans3[179]=33;
ans2[180]=10 , ans3[180]=34;
ans2[181]=10 , ans3[181]=34;
ans2[182]=10 , ans3[182]=34;
ans2[183]=10 , ans3[183]=34;
ans2[184]=10 , ans3[184]=34;
ans2[185]=10 , ans3[185]=34;
ans2[186]=10 , ans3[186]=34;
ans2[187]=10 , ans3[187]=34;
ans2[188]=12 , ans3[188]=31;
ans2[189]=12 , ans3[189]=31;
ans2[190]=12 , ans3[190]=31;
ans2[191]=12 , ans3[191]=31;
ans2[192]=12 , ans3[192]=31;
ans2[193]=12 , ans3[193]=31;
ans2[194]=12 , ans3[194]=31;
ans2[195]=12 , ans3[195]=31;
ans2[196]=12 , ans3[196]=31;
ans2[197]=17 , ans3[197]=27;
ans2[198]=12 , ans3[198]=31;
ans2[199]=12 , ans3[199]=31;
ans2[200]=12 , ans3[200]=31;
ans2[201]=12 , ans3[201]=31;
scanf("%d",&T);
while(T--){
	scanf("%d",&n);
	printf("1 %d %d\n",ans2[n],ans3[n]);
}
return 0;
}


### CDOJ 1805 矩阵 题解 #### 问题分析 题目描述了一个 \( N \times M \) 的矩阵,其中每个元素要么是 \( 1 \),要么是 \( -1 \)[^1]。对于每一行 \( A_i \) 和每一列 \( B_j \),定义它们分别为该行和该列所有元素的乘积。目标是计算满足条件的所有不同矩阵的数量,即所有的 \( A_i, B_j \) 均等于给定值 \( K \)(\( K = 1 \) 或者 \( K = -1 \))[^1]。 此问题的核心在于如何通过动态规划或其他方法高效地枚举并统计符合条件的矩阵数量。 --- #### 动态规划思路 为了求解这个问题,可以采用动态规划的思想来优化时间复杂度。以下是具体的实现逻辑: 1. **状态定义** 定义 `dp[i][j]` 表示构建一个大小为 \( i \times j \) 的矩阵,并使每行和每列的乘积均为 \( K \) 所需的不同方案数[^2]。 2. **初始化** 对于单行或多列的情况,显然只有一种方式能够满足条件(全填入 \( 1 \)),因此有: \[ dp[1][j] = dp[i][1] = 1 \quad (i, j \geq 1) \] 3. **转移方程** 转移关系基于子问题分解: - 如果当前矩阵的高度大于宽度 (\( i > j \)),则可以通过减少高度的方式继承更小子问题的结果; \[ dp[i][j] = dp[i-j][j] + dp[i][j-1] \] - 若两者相等,则额外增加一种新的可能性; \[ dp[i][i] = 1 + dp[i][i-1] \] - 否则保持不变: \[ dp[i][j] = dp[i][i] \] 4. **最终结果提取** 输入整数 \( n \),表示需要解决的是 \( n \times n \) 大小的正方形矩阵情况下的计数值,故只需返回 `dp[n][n]` 即可完成任务。 --- #### 实现代码 下面是完整的程序实现,采用了上述提到的状态转换规则以及边界处理机制: ```cpp #include <iostream> using namespace std; #define MAXN 121 int dp[MAXN][MAXN] = {0}; // 初始化 DP 数组 void init_dp() { int i, j; for (i = 1; i <= 120; ++i) { dp[1][i] = dp[i][1] = 1; // 初始条件设置 } for (i = 2; i <= 120; ++i) { for (j = 2; j <= 120; ++j) { if (i < j) { dp[i][j] = dp[i][i]; } else if (i == j) { dp[i][j] = 1 + dp[i][j - 1]; } else if (i > j) { dp[i][j] = dp[i - j][j] + dp[i][j - 1]; } } } } int main() { init_dp(); // 进行动态规划预处理 int n; while (cin >> n && n >= 1) { cout << dp[n][n] << endl; // 输出对应规模下矩阵数目 } return 0; } ``` --- #### 结果解释 运行以上代码后,输入任意自然数 \( n \),即可得到对应的 \( n \times n \) 尺寸矩阵中符合要求的总数目。注意这里假定了行列长度一致的情形;如果扩展到一般矩形区域,则还需进一步调整算法框架适应变化范围内的参数设定。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值