XSY2759 coin DP 線性插值

2022-03-25 17:38:25 字數 1260 閱讀 6080

有\(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,輸出它的二進位制數呀?難道你不想幫幫她嗎?輸入 輸入有多個資料,資料以...