专栏文章
题解:AT_abc192_f [ABC192F] Potion
AT_abc192_f题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mioqx2jv
- 此快照首次捕获于
- 2025/12/02 23:41 3 个月前
- 此快照最后确认于
- 2025/12/02 23:41 3 个月前
题意
在 个数里选取任意个数,设个数为 ,求 最小值。
思路
首先可以发现所有数的总和不会超过 。
范围较小,考虑枚举选取个数。
设个数为 ,求出 ,记为 ;求出 ,记为 。我们现在要选出一些数,使它们的总和取模 等于 ,且选取个数为 才能符合要求。
考虑 dp,设 表示当前选取到第 个数,选了 个数,余数为 ,选取数的最大值。
边界:,。
转移:
- 当前不选,。
- 当前选,。
两者取最大值。
答案为 。
对于每个 的情况做一次 dp,计算答案。
时间复杂度 ,空间复杂度 ,可以通过。
CPP#include<bits/stdc++.h>
using namespace std;
const int N=105;
int n,a[N];
unsigned long long x,ans=1e18+1;
long long dp[N][N][N];
void DP(int K){
dp[0][0][0]=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=i;j++)
for(int k=0;k<K;k++){
if(dp[i-1][j][k]!=-1)
dp[i][j][k]=dp[i-1][j][k];
if(j>0&&dp[i-1][j-1][(k-a[i]%K+K)%K]!=-1)
dp[i][j][k]=max(dp[i-1][j-1][(k-a[i]%K+K)%K]+a[i],dp[i][j][k]);
}
}
int main(){
cin>>n>>x;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++){
memset(dp,-1,sizeof(dp));
DP(i);
if(dp[n][i][x%i]!=-1)
ans=min(ans,(x-dp[n][i][x%i])/i);
}
cout<<ans;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...