小信的装备 WA0pts求助

#include<bits/stdc++.h>
using namespace std;
const int N=1e7;
int n,cnt,a[200005],f[700000],num[N+5],dp[N+5];
bool prime[N+5];
void getprime(){
  memset(prime,true,sizeof(prime));
  prime[0]=prime[1]=false;
  for(int i=2;i<=N;i++){
	if(prime[i]) f[++cnt]=i;
	for(int j=1;j<=cnt&&i*f[j]<=N;j++){
      prime[i*f[j]]=false;
      if(i%f[j]==0) break;
	}
  }
  return;
}
int main(){
    freopen("item.in","r",stdin);
    freopen("item.out","w",stdout);
    getprime();
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
      scanf("%d",&a[i]);
      num[a[i]]++;
    }
    for(int i=1;i<N;i++){
      dp[i]=max(dp[i],num[i]);
      for(int j=1;i*f[j]<N&&j<=cnt;j++){
        dp[j]=max(dp[j],num[j]+dp[i]);
      }
    }
    int ans=0;
    for(int i=1;i<N;i++) ans=max(ans,dp[i]);
    printf("%d",ans);
    return 0;
}

样例过了吗?

转移公式错了,num是看他有没有出现过,所以不能num[j]+dp[j],转移方程应该是dp[a[i]]=max(dp[a[i]],dp[j]+1),如果另一个和他成对的因数也出现过,在转移dp[a[i]]=max(dp[a[i]],dp[a[i]/j]+1)(注意排除完全平方数的情况)

没看懂,我这是在更新后面的状态,按照老师的思路来的,要不你把循环整个发出来?

差不多懂了,就是枚举 a_i 的所有因子,如果之前出现过这个数,就更新 f 数组,如果另一个对应的因子也出现过且不是完全平方数,也更新,对吧?

那就不用筛质数了?

你可要可不要(看你自己)

不用,这就够了

已A
解决方案给你了,吴梓峤
@稻叶昙 关帖