大师
题目链接:https://www.luogu.com.cn/problem/P4933
题意:
给定数组,每次可以任选数组中的元素消除,求能构成等差数列的方案数
思路:
记 dp[i,j] 为以i作结尾,公差为j的等差数列数量
枚举i之前的那些数k
j=a[i]-a[k]
dp[i,j] <-- dp[k,j] +1 (因为k,i可以构成有两个元素的等差数列)
因为公差可以相同并且通过不同位置转移的方案数需要叠加,所以dp[i,j]需要+=
每一个以i结尾的还有单独它一个数的情况
注意公差可以为负,所以需要将其离散
#include<bits/stdc++.h> #define rep(i,a,n) for(int i=a;i<=n;i++) #define pb push_back #define endl "\n" #define int long long #define fi first #define se second //#pragma GCC optimize(3) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef __int128 lll; typedef pair<int,int> pii; const int inf=0x3f3f3f3f; const ll llmax=LLONG_MAX; const int maxn=1e5+5; const int mod=998244353; const int N=2e4+5; const int p=2e4; int ans; int cal(int cnt){ return cnt*(cnt+1)/2; } void solve(){ int n;cin>>n; vector<int>a(n+1,0); for(int i=1;i<=n;i++){ cin>>a[i]; } vector<vector<int>>dp(n+1,vector<int>(2*N,0)); for(int i=1;i<=n;i++){ for(int j=1;j<=i-1;j++){ int dif=a[i]-a[j]+p; dp[i][dif]=(dp[i][dif]%mod+(dp[j][dif]+1)%mod)%mod; ans=(ans%mod+(dp[j][dif]+1)%mod)%mod; } ans=(ans+1)%mod; } cout<<ans<<endl; } signed main() { ios::sync_with_stdio(false),cin.tie(0); int T=1; while(T--){ solve(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现