Codeforces 264B (Good Sequences)

题目:http://codeforces.com/problemset/problem/264/B

题意:给你一串递增序列,找出最长的一段子序列,满足两两相邻的两个数不互质,并求出最长的子序列长度;


思路:官方题解上说是个DP,但我觉得我的做法好像不是DP。。就hash了一下每个数的因子;比赛的时候,算错了复杂度,直接套了个O(n^2)求最长上升子序列的上去,还过了样例,不过最后被hack了。。这题比赛时能做对的,但是被hack的时候剩下时间也不多了,所以也就没什么时间去做了;我的做法是开一个长度为n的vector,然后把第i个数的因数都存进第i个vector中;再开一个数组dp[因子]存储当前以因子x为终点最长的子序列长度,然后再从头开始遍历,将第i个数的所有因子dp[因子]++,然后再求出第i个数的因子中数目最大的那个,记为Max,然后更新,

dp[第i个数的所有因子 = Max;答案就是res = max(dp[i])1<= i <=num[n] ,其实是出现过的所有因子,看下样例找规律也挺好找的;

#include<cstdio>
#include<vector>
#include<math.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#define PB push_back
using namespace std;

const int N = 100010;
const int M = 510;
const int MININF = -10000000;
int num[N], dp[N];
vector<int> V[N];

void getDiv(int x,int idx){
	if(x == 1){
		V[idx].PB(1);
		return ;
	}
	int len = (int)sqrt(x);
	for(int i = 2;i <= (int)len;i++)
		if(x % i == 0)
			V[idx].PB(i), V[idx].PB(x / i);
	if(len * len == x)
		V[idx].pop_back();
		V[idx].PB(x);
}

int main(){
	int i, j, n;
	scanf("%d", &n);
	for(i = 1;i <= n;i++){
		scanf("%d", &num[i]);
		getDiv(num[i], i);
	}
	memset(dp, 0, sizeof(dp));
	for(i = 1;i <= n;i++){
		int Max = MININF;
		for(j = 0;j < (int)V[i].size();j++){
			dp[V[i][j]]++;
			Max = max(Max, dp[V[i][j]]);
		}
		for(j = 0;j < (int)V[i].size();j++)
			dp[V[i][j]] = Max;
	}
	int res = MININF;
	for(i = 1;i <= num[n];i++)
		res = max(res, dp[i]);
	cout<< res << endl;
	
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值