uoj140 UER 4 被粉碎的數字

2022-03-26 22:01:18 字數 1017 閱讀 3399

題目

看起來就像是數字\(\rm dp\)

不妨從豎式乘法的角度來考慮這個問題

為了方便處理進製,我們得從低位向高位填數

設\(dp[i][0/1][j][p][t]\)表示填到了第\(i\)位,卡不卡上界,\(f(x)=j\),\(f(k\times x)=p\)(不計算最高位),需要向最高位進\(t\)的\(x\)有多少個

這裡的卡上界比較奇怪,如果這一位上填的數大於\(r\)這一位上的數,那麼就一定卡了上界,如果小於這一位上的數,那麼就一定不卡上界,如果和原來的數相等,那麼就繼續之前的狀態

所以這個\(0/1\)就表示後面的\(i\)為和\(r\)後\(i\)位的大小關係,如果填的數大於\(r\)後\(i\)為,那麼這個狀態就是\(1\);否則就是\(0\)

至於轉移,就比較簡單,我們列舉這一位上填什麼數\(y\),那麼對於\(x\),數字和增加了\(y\),對於\(k\times x\),這一位上直接來乙個乘法是\(k\times y\),還有之前的進製\(t\),於是就是\((k\times y+t)\% 10\),新的進製就是\((k\times y+t)/10\)

但是這樣我們填到\(r\)的最高位之後可能還有一些進製沒有處理,於是再往前多處理\(3\)位把進製處理完

最後的答案就是\(\sum_dp[\lg_][0][i][i][0]\),即\(x\)的數字和等於\(f(k\times x)\)的情況,但是這樣多了一維非常難受,考慮的最後只要求\(j=p\),所以我們直接把\(j-p\)看成一維狀態就好了

**

#include#define re register

#define ll long long

ll dp[25][2][1000][500];

int m,w,a[25],m=250;ll n;

inline void split(ll x)

int main()

printf("%lld\n",dp[w+3][0][0][m]-1);

return 0;

}

uoj 209 UER 6A 票數統計

給出n個數,每個數是0或1.再給出m個限制,每個限制 x,y 表示 前x個數中有y個1 或 後y個數中有x個1 求這樣的序列的個數。n 5000,m 1000 再一次被uer給虐了。其實這道題劼鏼爺已經講的很清楚了。撲通撲通跪下來 當x y的時候,很顯然已經確定這個限制是限制字首還是字尾的。當x y...

UOJ 209 UER 6 票數統計

原題鏈結 妹滋滋是乙個善於程式設計的女孩子。但是某一天,她一不小心把 uoj 後台的票數統計程式寫錯了。本來嘛在這種根本沒有什麼用的功能上出了 bug 也沒有什麼大關係,但是又有某一天,uoj 突然就開始搞全民公投了。這可怎麼辦呢?如果這個訊息讓別人知道的話自己肯定會被查表,更不要說讓所有使用者重新...

UOJ 210 UER 6 尋找罪犯

有n個人分為好人和壞人,說了m句話。好人不會說假話,壞人至多說一句謊話。求出一組解,滿足要求。利用2 sat拆點,乙個人拆成兩個點,表示他是好人和壞人。然而這樣的話邊數是m 2的,所以用前 字尾和優化構圖即可。1 include 2 using namespace std 34 const int ...