搜尋演算法,運用餘數優化
lcd (x, y) = ( if x&1 && y&1: lcd(x, (x-y)/2); else lcd(x/2 if x&1==0, y/2 if y&1==0) )
x=x1x2..xi . y1y2...yj(z1 z2... zk) =/10^j + m/10^j
其中 迴圈節 m = z1 z2 ... zk/ (10^k -1)
所以 x = [+ / (10^k -1) ] /10^j =
[ *(10^k -1) +]/ [(10^k -1)*(10^j ) ], 化簡就可。
反向: 給出 n,m 求 n/m的迴圈節:
n/m = k + 0.y1y2...yj(z1 z2... zk)
t/m = 0.y1y2...yj(z1 z2... zk) = y/10^j + z/ [ 10^j *(10^k - 1) ]
乙個重要的結論是0.(z1z2...zk) = /(10^k-1), 比如 0.(353) = 353/(1000-1) = 353/999.
2 給定a1~ak,以及推導公式ak+1 <= a1~ak,最快的辦法求到 an
方法:矩陣加速(專用於求解k階遞推數列) 或 特徵方程(會存在無理數)
二分( 按照縱線二分)
轉化為帶物品數量限制的揹包重量問題 , o(n^2*sum),n=obj_cnt, sum=w_total
//bool[i][j]: 裝i個物品,能否裝到重量j
bool[0][0] = true
for k=1 to obj_cnt: //揹包問題最外層迭代一定是物品,因為物品只能裝一次
for i=1 to obj_cnt/2:
for j = w_total to obj_w[k]:
bool[i][j] = bool[i-1][j] || bool[i-1][j-obj_w[k]]
5 最短摘要的生成
6 桶中取黑白球算概率:
排列組合 + dp(類似還有卡特蘭數f [ 2n ] = e( f[ 2n-2*i-2 ] * f[ 2*i ], i=0~n-1 ) = c(2n, n) - c(2n, n-1) )
cnt[sum][white]為還剩下sum個球,白球數量white的概率排列組合數。
cnt[200][100] = 1
cnt[sum][white] = cnt[sum+1] [ white ]*3 + cnt[sum+1] [ white+2] //四種取法,對應四種上乙個狀態
最後 cnt[1][0] / (cnt[1][0] + cnt[1][1])
int a[21][21];
memset(a, 0, sizeof(a));
a[20][10]=1;
for(int i=19; i>=1; i--)
}cout<
還有一種方法: 白球的數量每輪減少0 或2, 所以白球數量始終是偶數,如果只剩乙個球,則必定是黑球。
7 螞蟻爬桿
找所有螞蟻都離開桿子的最短和最長時間。呵呵,簡單轉化一下就變成同時求最大最小值了。
8 取石子遊戲數學推導
帶狀態壓縮(二進位制,表示第幾個數被用到)的dp
s[ bits ] = map< result, cnt > // bits 表示哪些數字被用到, result表示計算結果, cnt表示得到該結果的方法數
inline int calc(int tt, int a, int op, int b, bool & tag)
switch(op)
return a/b;}}
tag= false; return 0;
}bool 24game(vector&num)}}
}}}}
return s[15][24] > 0;
}
10 數字啞謎和回文
啞謎: 數學推理
回文: 列舉「我」和寺,很快能夠 找到人過大佛四*我 = 是佛。的所有解
he^2 = she, 類似, (10*h +e )^2 = h^2*100 + e^2 + 20*h*e = s*100 + 10*h + e, 則 e^2 %10 = e, e = 1、5、6、0
e = 1: 1 + 20h + 100h^2 = 1 + 10h + 100s, 10h = 100(s-h^2), h = 10(s-h^2), s=h^2, h=0, s=0 不行
e = 5....
10 俄羅斯方塊
二進位制表示塊
11 掃雷
12 數獨
方法一: dp
value[ volume ] [ obj_i ] 表示對obj_i飲料物品分組進行裝包,得到的最大滿意度
value[ volume ] [ obj_i ] = max ( value[volume - k* w[i] ] [ obj_i - 1] + v[i] * k, k = 0 ~ c[i] ) 即對重量為volume狀態,輪番使用分組中的物品
for i = 1 to n://分組
for volume=max_volume to k*w[i]://每個重量
for k = 1 to c[i]://每個分組物品
value[ volume ] [ obj_i ] = max ( value[volume - k* w[i] ] [ obj_i - 1] + v[i] * k //上乙個分組遞推到本分組
或者:for i = 1 to n://分組
for k = 1 to c[i]://每個分組物品
for volume=max_volume to k*w[i]://每個重量
value[ volume ] [ obj_i ] = max ( value[volume - k* w[i] ] [ obj_i - 1] + v[i] * k
方法二:記憶化搜尋(dfs+dp)
一些不需要用到的狀態就不用算了
方法三: 貪心法
考慮到 max_volume 是乙個二進位制的數, 那麼每次從最低位找,找到可以用於填充這一位的飲料
比如第 j(j>=0)位, 對應於可以用的飲料為 ( w=2^k, value=xx ),其中k<=j
根據貪心策略找到最好的、這一位可用的飲料。使用 2^(j-k)單位 。
14 光影切割問題
根據交點個數,能夠推導直線分割的面數, 即cnt(0)=1, cnt (n) = cnt(n-k) + k+1 , cnt(n) = e(ki) + n=交點個數+n+1
所以o(n^2) 列舉獲得所有交點。o(mlogm)為對交點排序。
另外,可以使用逆序對個數來算交點
如直線跟兩邊的邊框縱線相交,如線1在兩條邊框上交點分別為(y1=1, y2=10),而另乙個線為(y1=10, y2=1),那麼他們有乙個逆序對,也必有乙個交點。
這道題直覺上可以greedy,但其實不行,必須states dynamic planning
cnt[y1][y2][y3][y4][y5] 表示各種書分別為y1,y2..y5,其中y1>=y2>=y3>=y4>=y5,的最大折扣數
這個dp存在乙個優化:
對任意狀態cnt[y1][y2][y3][y4][y5] ,後續除了<[1,2,3],4,5>一定存在
<[1 2 3] 4>這種含有4而不含5的放書方法,
同理後續除了<[1,2],3,4>一定存在
<[1,2] 3>這種含有3不含4的方法
所以遞推公式變得簡單了:cnt[y1][y2][y3][y4][y5] = max( cnt[y1-1][y2-1][y3-1][y4-1][y5-1] if(y5>=1), cnt[y1-1][y2-1][y3-1][y4-1][y5] if(y4>=1), cnt[y1-1][y2-1][y3-1][y4][y5] if(y3>=1)。。。, cnt[y1-1][y2][y3][y4][y5] if(y1>=1) ).
第一章:
1 繪製cpu佔用率曲線
程式設計之美 微軟技術面試心得
內容介紹 第1章 遊戲之樂 遊戲中碰到的題目.1 1.1 讓cpu佔用率曲線聽你指揮.3 1.2 中國象棋將帥問題.13 1.3 一摞烙餅的排序.20 1.4 買書問題.30 1.5 快速找出故障機器.35 1.6 飲料供貨.40 1.7 光影切割問題.45 1.8 小飛的電梯排程演算法.50 1....
微軟程式設計之美 初賽
相似字串對於兩個長度相等的字串,我們定義其距離為對應位置不同的字元數量,同時我們認為距離越近的字串越相似。例如,0123 和 0000 的距離為 3,0123 和 0213 的距離則為 2,所以與 0000 相比,0213 和 0123 最相似。現在給定兩個字串 s1 和 s2,其中 s2 的長度不...
程式設計之美閱讀心得
3.30 我的結論是 1 如果存在乙個對a的安全狀態t,那麼如果t 能夠在一步轉為t,則t 是a的必敗狀態。2 此題的思路的關鍵是確定一種a的必勝的模式 比如分偶數堆,每堆個數相同。其實思路應該更簡單一些,就是對m分情況討論,如果m是偶數,如何分堆必勝 兩堆,個數相等。3 對m為奇數的情況,還沒有想...