Exact Payment 题解

值域太大,直接统计不行。一位位讨论应是更加选择。设现在讨论第 ii 位,即权值为 10i110^{i-1} 的位,更高位没必要讨论。所以先 mod10i \bmod 10^i

我们只要考虑该位上的最大值。先每次暴力选数,然后加优化。

现在从小到大有三个状态 x,y,zx,y,z。如果 zx10i1z-x\leq10^{i-1} 那就可以舍去 yy。证明:在最高位上,包括 zz 的与包括 xx 的选商品策略的钱数和最多相差 11,而包括 yy 的策略必与包括 x,zx,z 策略中至少其一相同。

加优化后状态数很少。复杂度 O(nlog10V)O(n\log_{10}V)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e4+10;
int n,a[N],dp[25],ans;
//dpi 选出来的一个值 
signed main() {
	cin>>n;
	for(int i=1;i<=n;i++) {
		cin>>a[i];
	}
	int base=1;
	for(int i=1;i<=17;i++) {
		base*=10;
		int m=1;
		dp[m]=0;
		for(int j=1;j<=n;j++) {
			for(int k=1;k<=m;k++) {
				dp[m+k]=(dp[k]+a[j])%base;
			}
			sort(dp+1,dp+1+m*2);
			int ix=2;
			for(int k=3;k<=2*m;k++) {
				if(dp[k]-dp[ix-1]<base/10) dp[ix]=dp[k];
				else dp[++ix]=dp[k];
			}
			m=ix;
		}
//		cout<<dp[m]/(base/10)<<endl;
		ans+=dp[m]/(base/10);
	}
	cout<<ans;
	return 0;
}
/*
3
43 24 37
*/
posted @ 2023-11-09 09:46  cjrqwq  阅读(7)  评论(0)    收藏  举报  来源