【题解】AT_arc153_d [ARC153D] Sum of Sum of Digits

AT_arc153_d】题解

一:【题意】

给定一个序列a,要求找出一个非负整数x,使得f(a[1]+x)+f(a[2]+x)+...+f(a[n]+x)最小
f(x):十进制各数位和

二:【解法】

按照数位划分阶段
dp[i][j]:考虑了[1,i],第i位进位为j的数位和最小值
如何转移呢
将a按照数位[1,i-1]进行降序排序,则向i进位的一定是某个前缀
枚举x的i数位,枚举i-1阶段的进位k,统计此阶段进位tot,和a数位i之和sum
dp[i][tot]=min(dp[i][tot],dp[i-1][k]+sum)

三:【代码】

#include<bits/stdc++.h>
#define inf 2e9
using namespace std;
const int N=2e5+10;
int a[N];
int dp[11][N];
int w;
bool cmp(int a,int b){
	return a%w>b%w;
}
int main(){
	for(int i=0;i<11;i++){
		for(int j=0;j<N;j++) dp[i][j]=inf;
	}
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	w=1;
	dp[0][0]=0;
	for(int i=1;i<=10;i++,w*=10){
		sort(a+1,a+1+n,cmp);
		for(int ad=0;ad<=9;ad++){
			int tot=0,sum=0;
			for(int k=1;k<=n;k++){
				int x=a[k]/w%10+ad;
				tot+=(x>=10);
				sum+=x%10;
			}
			dp[i][tot]=min(dp[i][tot],dp[i-1][0]+sum);
			for(int k=1;k<=n;k++){
				int x=a[k]/w%10+ad;
				if(x==9){
					tot++;
					sum-=9;
				}
				else sum++;
				dp[i][tot]=min(dp[i][tot],dp[i-1][k]+sum);
			}
		}
	}
	int ans=inf;
	for(int i=0;i<=n;i++) ans=min(ans,dp[10][i]+i);
	cout<<ans<<"\n";
	return 0;
}
posted @ 2025-12-19 10:30  Ming3398  阅读(1)  评论(0)    收藏  举报