有\(n\)種面值不同的硬幣,每種有無限個,且任意兩個\((x,y)\)要麼\(x\)是\(y\)的倍數,要麼\(y\)是\(x\)的倍數。
你要取\(m\)元錢,問你有多少種不同的取法。
\(n\leq 50,m\leq ^\)
假設面值為\(a_1,a_2,\ldots,a_n\)
先把所有硬幣按面值從小到大排序。
那麼考慮從小到大取錢。
如果前面\(i\)種面值已經取完了,那麼取的錢數\(\bmod\)
\(a_\)已經確定了。
有這麼乙個dp:設\(f_i(x)\)為取完了前面\(i\)種面值的硬幣,取的錢數為\(xa_i+m\bmod a_i\)的方案數。
轉移:列舉\(i\)這種硬幣用了多少個(或者說剩下了多少個):
\[\begin
f_i(x)&=\sum_^x f_(\frac})\\
&=\sum_^x f_(bj+c)\\
\end
\]我們很容易發現\(f_i(x)\)是乙個\(i\)次函式。
那麼只需要求\(f_i(0)\ldots f_i(i)\)就可以了。
每次可以通過線性插值求出。
時間複雜度:\(o(n^3)\)
#include#include#includeusing namespace std;
typedef long long ll;
const int p=998244353;
ll fp(ll a,ll b)
int f[60][60];
int ifac[60];
int inv[60];
int pp[60];
int *pre=pp+1;
int suf[60];
ll a[60];
int n;
ll m;
int c[60];
int gao(int id,ll x)
int main()
f[1][0]=1;
f[1][1]=1;
for(int i=2;i<=n;i++)
for(int j=0;j<=i;j++)
f[i][j]=(f[i][j-1]+gao(i-1,(j*a[i]+m%a[i])/a[i-1]))%p;
int ans=gao(n,m/a[n]);
ans=(ans+p)%p;
printf("%lld\n",ans);
return 0;
}
SICP練習 99 練習2 75
通過模仿書上的make from real imag函式來完成此題。define make from mag ang x y define dispatch op cond eq?op real part x cos y eq?op imag part x sin y eq?op magnitude...
275 最短路徑問題
275.最短路徑問題 描述 提交自定義測試 題目描述 平面上有n個點,每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點間的直線距離。現在的任務是找出從一點到另一點之間的最短路徑。輸入描述 輸入檔案共n m ...
275 隊花的煩惱一
時間限制 3000 ms 記憶體限制 65535 kb 難度 1 描述 acm隊的隊花c小 經常抱怨 c語言中的格式輸出中有十 六 十 八進位制輸出,然而卻沒有二進位制輸出,哎,真遺憾!誰能幫我寫乙個程式實現輸入乙個十進位制數n,輸出它的二進位制數呀?難道你不想幫幫她嗎?輸入 輸入有多個資料,資料以...