其他分享
首页 > 其他分享> > 1573 分离与合体(LOJ10151) 区间动规 区间动规合并过程

1573 分离与合体(LOJ10151) 区间动规 区间动规合并过程

作者:互联网

总目录

在线测评地址(ybt)

在线测评地址(LOJ)

1.区间动规 区间动规合并过程

ybt

通过

测试点结果内存时间
测试点1答案正确1708KB8MS
测试点2答案正确628KB2MS
测试点3答案正确656KB2MS
测试点4答案正确764KB2MS
测试点5答案正确788KB2MS
测试点6答案正确1148KB2MS
测试点7答案正确1388KB4MS
测试点8答案正确1640KB7MS
测试点9答案正确1704KB8MS
测试点10答案正确1708KB8MS

LOJ

 题意挺玄乎,弄懂样例是关键。

7
1 2 3 4 5 6 7

dp[1][2]=(1+2)*1=2
dp[2][3]=(2+3)*2=10
dp[3][4]=(3+4)*3=21
dp[4][5]=(4+5)*4=36
dp[5][6]=(5+6)*5=55
dp[6][7]=(6+7)*6=78

dp[1][3]=max(dp[2][3]+(1+3)*1,dp[1][2]+(1+3)*2)=max(14,10)=14
dp[2][4]=max(dp[3][4]+(2+4)*2,dp[2][3]+(2+4)*3)=max(33,28)=33
dp[3][5]=max(dp[4][5]+(3+5)*3,dp[3][4]+(3+5)*4)=max(60,53)=60
dp[4][6]=max(dp[5][6]+(4+6)*4,dp[4][5]+(4+6)*5)=max(95,86)=95
dp[5][7]=max(dp[6][7]+(5+7)*5,dp[5][6]+(5+7)*6)=max(138,127)=138

dp[1][4]=max(dp[2][4]+(1+4)*1,dp[1][2]+dp[3][4]+(1+4)*2,dp[1][3]+(1+4)*3)=max(38,33,29)=38
dp[2][5]=max(dp[3][5]+(2+5)*)
dp[3][6]=
dp[4][7]=

dp[1][5]=
dp[2][6]=
dp[3][7]=

dp[1][6]=
dp[2][7]=

dp[1][7]=

实在写不下去了,编码吧,先看看最大值是否能核上。

核验最值及中间过程的代码如下:

#include <bits/stdc++.h>
#define maxn 310
using namespace std;
unsigned int a[maxn],dp[maxn][maxn];
int main(){
	int n,lt,rt,k,i,len;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%u",&a[i]);
	for(len=1;len<=n-1;len++)
		for(lt=1;lt<=n;lt++){
			rt=lt+len;
			if(rt>n)break;
			for(k=0;k<len;k++)
				dp[lt][rt]=max(dp[lt][rt],dp[lt][lt+k]+dp[lt+k+1][rt]+(a[lt]+a[rt])*a[lt+k]);
			printf("dp[%d][%d]=%u\n",lt,rt,dp[lt][rt]);
		}
	printf("%u\n",dp[1][n]);
	return 0;
}

上述代码对应的输入输出数据如下:

7
1 2 3 4 5 6 7

dp[1][2]=3
dp[2][3]=10
dp[3][4]=21
dp[4][5]=36
dp[5][6]=55
dp[6][7]=78
dp[1][3]=14
dp[2][4]=33
dp[3][5]=60
dp[4][6]=95
dp[5][7]=138
dp[1][4]=38
dp[2][5]=74
dp[3][6]=122
dp[4][7]=182
dp[1][5]=80
dp[2][6]=138
dp[3][7]=212
dp[1][6]=145
dp[2][7]=230
dp[1][7]=238
238

该题需要记录区间合并过程。

打印区域犯难了,再仔细读题,发现,还是对打印区域进行了具体说明:

例如先打印一分为二的区域,然后从左到右打印二分为四的分离区域,然后是四分为八的……

样例对应的分裂过程如下:

b[1][7]
b[1][1] b[2][7] 输出1
b[1][1] b[2][2] b[3][7] 输出2
b[1][1] b[2][2] b[3][3] b[4][7] 输出3
b[1][1] b[2][2] b[3][3] b[4][4] b[5][7] 输出4
b[1][1] b[2][2] b[3][3] b[4][4] b[5][5] b[6][7] 输出5
b[1][1] b[2][2] b[3][3] b[4][4] b[5][5] b[6][6] b[7][7] 输出6

分裂的输出还是比较考验思维的。

基本思路:记录区间动规过程,一遍一遍的打印分裂位置,具体可见代码。

区间动规 区间动规合并过程 代码如下:

#include <bits/stdc++.h>
#define maxn 310
using namespace std;
unsigned int a[maxn],dp[maxn][maxn],b[maxn][maxn],vis[maxn];
int main(){
	int n,lt,rt,k,i,len;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%u",&a[i]);
	for(len=1;len<=n-1;len++)
		for(lt=1;lt<=n;lt++){
			rt=lt+len;
			if(rt>n)break;
			for(k=0;k<len;k++)
				if(dp[lt][rt]<dp[lt][lt+k]+dp[lt+k+1][rt]+(a[lt]+a[rt])*a[lt+k]){
					dp[lt][rt]=dp[lt][lt+k]+dp[lt+k+1][rt]+(a[lt]+a[rt])*a[lt+k];
					b[lt][rt]=lt+k;
				}
		}
	printf("%u\n",dp[1][n]);
	int print=1;//打印分裂过程 
	vis[n]=1;//关键点
	while(print){
		print=0;
		lt=1;
		for(rt=1;rt<=n;rt++)
			if(vis[rt]){
				k=b[lt][rt];
				if(k){
					printf("%u ",k);
					vis[k]=1;
					print=1;
				}
				lt=rt+1;//关键点
			}
	} 
	printf("\n");
	return 0;
}

该题习得了什么?无符号整数的输入与输出。 %u

独立写出了区间动规的分裂过程。

标签:测试点,int,max,LOJ10151,maxn,动规,区间,dp
来源: https://blog.csdn.net/mrcrack/article/details/122331168