2022 绍兴市小学组 3.美感(beautiful)
首先将 \(\forall a_i\gets a_i\bmod m\)。
题目要求求“最少删除多少个数”,那么我们可以转换一下成:“最多保留多少个数”。
考虑 \(\mathcal O(n^2)\) 做法,设 \(f_i\) 表示以 \(i\) 为序列最后一个能够保留数的最多数量,则有 \(f_i = \max\limits_{j=1}^{i-1} [\left(a_i+a_j\right)\bmod m = 0]f_j + 1\),最终答案为 \(n - \left(\max\limits_{i=1}^n f_i\right)\),注意判断最优答案是长度为 \(1\) 的情况。
初始 \(\forall f_i = 1\)。
这样有 \(90\texttt{pts}\)。
# include <bits/stdc++.h>
# define int long long
# define rint register int
# define ME ;
# define AK 0
# define SX2022 return
inline int read();
inline void write(int x);
inline void writesp(int x);
inline void wrietln(int x);
//---------------------------------
using namespace std;
const int N = 1e5 + 10;
int n ,m ,ans ,a[N] ,f[N];
inline void fre(){
freopen("beautiful.in" ,"r" ,stdin);
freopen("beautiful.out" ,"w" ,stdout);
}
signed main(){
n = read() ,m = read();
for(rint i = 1 ;i <= n; i ++)
a[i] = read() ,a[i] %= m;
f[1] = ans = 1;
for(rint i = 2 ; i <= n ;i ++){
for(rint j = 1; j < i ;j ++)
if((a[i] + a[j]) % m == 0) f[i] = max(f[i] ,f[j] + 1);
ans = max(ans ,f[i]);
}
if(n <= 5000) printf("%lld\n" ,n - ans);
else printf("%lld\n" ,n - 1);
SX2022 AK ME
}
inline int read(){
int s = 0 ,w = 0;
char c = getchar();
while(!isdigit(c)){
w |= (c == '-');
c = getchar();
} while(isdigit(c)){
s = (s << 1ll) + (s << 3ll) + (c ^ 48);
c = getchar();
} return w ? -s : s;
} inline void write(int x){
if(x < 0) putchar('-') ,x = -x;
if(x >= 10) write(x / 10);
putchar (x % 10 | 48);
} inline void writesp(int x){
write(x) ,putchar(' ');
} inline void writeln(int x){
write(x) ,putchar('\n');
}
引理:\((k_1 + k_2) \bmod m = (k_1\bmod m + k_2\bmod m)\bmod m\)。
如果这个数可以保存,当且仅当有一个 \(j\)(\(1\le j < i\)) 满足 \((a_i + a_j)\bmod m = 0\),逆推得出合适的一个 \(a_j = m - a_i\)。
设 \(f_i\) 表示以 \(i\) 为余数,并且为序列最后一个数的最多保留数量,则有 \(f_{a_i} = \max\left(f_{a_i} ,f_{m - a_i} + 1\right)\)。
最后的答案即为 \(\max\limits_{i=0}^m f_i\)。
# include <bits/stdc++.h>
# define int long long
# define rint register int
# define ME ;
# define AK 0
# define SX2022 return
inline int read();
inline void write(int x);
inline void writesp(int x);
inline void wrietln(int x);
//---------------------------------
using namespace std;
const int N = 1e5 + 10;
int n ,m ,ans ,ans1 ,ans2 ,b[N] ,a[N] ,f[N];
inline void fre(){
freopen("beautiful.in" ,"r" ,stdin);
freopen("beautiful.out" ,"w" ,stdout);
} signed main(){
n = read() ,m = read();
for(rint i = 1 ;i <= n; i ++)
a[i] = read() ,a[i] %= m;
for(rint i = 1 ; i <= n ;i ++){
int aj = m - a[i];
if(aj == m) aj = 0;
f[a[i]] = max(f[a[i]] ,f[aj] + 1);
} for(rint i = 0 ; i < m; i ++) ans = max(ans ,f[i]);
printf("%lld\n" ,n - ans);
SX2022 AK ME
}
inline int read(){
int s = 0 ,w = 0;
char c = getchar();
while(!isdigit(c)){
w |= (c == '-');
c = getchar();
} while(isdigit(c)){
s = (s << 1ll) + (s << 3ll) + (c ^ 48);
c = getchar();
} return w ? -s : s;
} inline void write(int x){
if(x < 0) putchar('-') ,x = -x;
if(x >= 10) write(x / 10);
putchar (x % 10 | 48);
} inline void writesp(int x){
write(x) ,putchar(' ');
} inline void writeln(int x){
write(x) ,putchar('\n');
}
本文来自博客园,作者:2021zjhs005,转载请注明原文链接:https://www.cnblogs.com/2021zjhs005/p/18382448

浙公网安备 33010602011771号