[NOIP模拟赛]天文观测

题目描述
Daisy找到了两个天文记录。它们都描述了相同的恒星系。系统中的每一个行星都可以有两个参数,每个参数都是一个正整数:行星的大小和它围绕恒星运行的距离。所有行星的轨道距离都是不同的,但是一些行星的大小可能相等。 
第一个记录是一个带有x个元素的数组A。这些元素给出了该恒星系中某x颗行星的相对大小,即:A[0]: A[1] : ... : A[x-1]。数组A所描述的行星是按它们与恒星的距离所确定的。(也就是说,下标小的元素对应于离恒星更近的行星。)
第二个记录是一个带有y个元素的数组B。这些元素给出了该恒星系中某y颗行星的相对大小,即:B[0]: B[1] : ... : B[y-1]。数组B所描述的行星是按它们与恒星的距离所确定的。(也就是说,下标小的元素对应于离恒星更近的行星。)
请注意,被记录的行星并不一定是连续的。例如,如果包含了行星P、Q、R、S、T和U,那么第一个记录可能会比较P、R和S,而第二个记录则比较Q、R、T和U。
我们假设两个记录都是正确的。请求出该恒星系中最小可能的行星总数。


输入格式

第1行:1个整数x,表示A数组元素的个数
第2行:x个整数,表示数组A
第3行:1个整数y,表示B数组元素的个数
第3行:y个整数,表示数组B


输出格式

第1行:1个整数,表示恒星系中最少的行星数量
输入样例
5
1 2 1 2 1
5
2 1 2 1 2


输出样例

6
样例说明

根据行星的大小比较,可以发现,最少需要6颗行星



题解

用两个序列的总长减去可以相同的部分,两个序列的最长上升子序列就是可以相同的部分。但还有一个问题:序列中的大小是相对的,可以同时扩大或缩小相同的倍数,因此枚举可能倍数相乘。时间复杂度O(n^4)。


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=105;

int x, y, sum, arr[N][N];
int realA[N], realB[N], A[N], B[N];

int main() {
	scanf( "%d", &x ); for( int i=1; i<=x; i++ ) scanf( "%d", &realA[i] );
	scanf( "%d", &y ); for( int i=1; i<=y; i++ ) scanf( "%d", &realB[i] );
	sum=x+y;
	for( int a=1; a<=x; a++ ) 
		for( int b=1; b<=y; b++ ) {
			for( int i=1; i<=x; i++ ) A[i]=realA[i]*realB[b];
			for( int i=1; i<=y; i++ ) B[i]=realB[i]*realA[a];
			for( int i=1; i<=x; i++ )
				for( int j=1; j<=y; j++ ) {
					arr[i][j]=max( arr[i][j-1], arr[i-1][j] );
					if( A[i]==B[j] ) arr[i][j]=max( arr[i][j], arr[i-1][j-1]+1 );
				}
			sum=min( sum, x+y-arr[x][y] );
		}
	printf( "%d\n", sum );
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值