专栏文章

题解: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 个月前
查看原文

题意

NN 个数里选取任意个数,设个数为 KK,求 XAiK\frac{X-\sum A_i}{K} 最小值。

思路

首先可以发现所有数的总和不会超过 XX
NN 范围较小,考虑枚举选取个数。
设个数为 KK,求出 XmodKX \bmod K,记为 xx;求出 AimodKA_i \bmod K,记为 aia_i。我们现在要选出一些数,使它们的总和取模 KK 等于 xx,且选取个数为 KK 才能符合要求。
考虑 dp,设 dpi,j,kdp_{i,j,k} 表示当前选取到第 ii 个数,选了 jj 个数,余数为 kk,选取数的最大值。
边界:dp0,0,0=0dp_{0,0,0}=0dp0,j,k=inf(j>0k>0)dp_{0,j,k}=- \inf(j>0 \vee k>0)
转移:
  1. 当前不选,dpi,j,k=dpi1,j,kdp_{i,j,k}=dp_{i-1,j,k}
  2. 当前选,dpi,j,k=dpi1,j1,(kai+K)mod K+Aidp_{i,j,k}=dp_{i-1,j-1,(k-a_i+K) \bmod \ K}+A_i
两者取最大值。
答案为 dpn,K,Xdp_{n,K,X}
对于每个 KK 的情况做一次 dp,计算答案。
时间复杂度 O(n4)O(n^4),空间复杂度 O(n3)O(n^3),可以通过。
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 条评论,欢迎与作者交流。

正在加载评论...