abc403 D
作者:
绪方九段
,
2025-04-27 21:31:58
· 山东
,
所有人可见
,
阅读 2
D=0 任意两个不相等
D!=0 mod D 分类 不同类不影响
转化 如果两个数同余D,那么同时除以D,如果两数相同则相同,不同则一定不同
所以只需要对于每一个同余 做到不存在差为1的两个数即可 因为差唯一可以有作差等于D
经典问题 有序数组不存在相邻 至少删除几个数 股票问题
DP 0删除1不删
ai==ai-1
删
不删
ai==ai-1 + 1
取较小值
ai> ai-1
每一个分别跑 合在一起是ON的
草稿1
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
bool is[200005];
const int N = 2e5+10;
int dp[N];
map<int,int> st;
int a[N];
int main()
{
int n,D;
cin>>n>>D;
dp[0]=0;
for(int i=1;i<=n;i++){
cin>>a[i];
st[a[i]]++;
dp[i]= max(dp[i-1], dp[i-1] - (st[D+a[i]]+ (a[i]-D>=0? st[a[i]-D]:0) ) +1);
cout<<dp[i]<<endl;
}
cout<<n-dp[n]<<endl;
}
2 关键是理解不同类中 结果互不干涉
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10,D=1e6+5;
int n,d;
int dp[N][2];
vector<int> A[D];
int main()
{
scanf("%d %d",&n,&d);
for(int i=1;i<=n;i++){
int x;
scanf("%d", &x);
if(d) A[x%d].push_back(x/d);
else A[x].push_back(x);
}
int ans = 0;
for(int i=0;i<D;i++){
if(A[i].size()>1){
if(d==0){
ans+=A[i].size()-1;
continue;
}
sort(A[i].begin(),A[i].end());
dp[0][1]=0;
dp[0][0]=1;
for(int j=1;j<A[i].size();j++){
if(A[i][j]==A[i][j-1]){
dp[j][0] = dp[j-1][0] +1;
dp[j][1] = dp[j-1][1];
}else if(A[i][j] ==A[i][j-1] + 1){
dp[j][0] = min(dp[j-1][1],dp[j-1][0])+1;
dp[j][1] = dp[j-1][0];
}else{
dp[j][0] = min(dp[j-1][0],dp[j-1][1])+1;
dp[j][1] = min(dp[j-1][0],dp[j-1][1]);
}
}
ans += min(dp[A[i].size()-1][0],dp[A[i].size()-1][1]);
}
}
printf("%d\n",ans);
}