F - Valid payments Editorial
大佬题解
看了述题解我才刚理解题目意思。
Here, both Lunlun and the clerk used the minimum number of coins needed to represent those amounts of money.
这句话意味着任何数都能用a1…ana_1\dots a_na1…an这些面值的货币唯一表示
并且能够推导出:对于第iii种纸币的面值是aia_iai,使用次数一定小于mxi=ai+1aimx_i=\frac{a_{i+1}}{a_i}mxi=aiai+1
不妨设找的钱为bbb于是有X+b=yX+b=yX+b=y,将三个数用aia_iai表示有
X=kX1a1+kX2a2+⋯+kXnanX=k_{X1}a_1+k_{X2}a_2+\dots +k_{Xn}a_nX=kX1a1+kX2a2+⋯+kXnan
b=kb1a1+kb2a2+⋯+kbnanb=k_{b1}a_1+k_{b2}a_2+\dots +k_{bn}a_nb=kb1a1+kb2a2+⋯+kbnan
y=ky1a1+ky2a2+⋯+kynany=k_{y1}a_1+k_{y2}a_2+\dots +k_{yn}a_ny=ky1a1+ky2a2+⋯+kynan
且有:
①kbik_{bi}kbi和kyik_{yi}kyi至少有一个为0
②kyi<mxik_{yi}<mx_ikyi<mxi
fi,0/1f_{i,0/1}fi,0/1表示考虑第iii种位是否对i+1i+1i+1位进位的方案数
后续参考大佬题解
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<random>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=60;
ll a[N],mx[N],k[N];
ll x;
ll f[N][2];
int n;
int main()
{IO;int T=1;//cin>>T;while(T--){cin>>n>>x;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<n;i++) mx[i]=a[i+1]/a[i];for(int i=n;i;i--){k[i]=x/a[i];x%=a[i];}f[1][0]=1;if(k[1]) f[1][1]=1;for(int i=1;i<n;i++){f[i+1][0]+=f[i][0];if(k[i+1]) f[i+1][1]+=f[i][0];f[i+1][1]+=f[i][1];if(k[i+1]+1!=mx[i+1]) f[i+1][0]+=f[i][1];}cout<<f[n][0]<<'\n';}return 0;
}
理解的不是太清晰~~