樓主海外留學生,昨晚參加了宇宙節的演算法筆試,被折磨的死去活來。。。最後一題揹包問題,當時有思路但是沒想清楚怎麼實現,後來時間不夠了唉。今天把**寫出來了,希望有大佬可以看一下正確與否。
題目內容:
第一行輸入三個數n, m, s。第二行輸入乙個包含n個數的數列 l[i], i=0,...,n-1.
要求:輸出選取任意數量的數字使其總和達到s。運算過程中可以對數字進行階乘,但是每個數字只能最多階乘一次,而且階乘運算的總數不能大於m。
輸入例子:
3 1 1
1 1 1
輸出例子:
輸入例子:
3 2 6
1 2 3
輸出例子:
這道題是揹包問題的變形中的求方案總數問題,這是個二維問題(s,m)。其狀態轉移方程為:g[v, m] = g[v, m]+g[v-l[i]][m]+g[v-l[i]!][m-1]。初始狀態為g[0][0] = 1。但是考試時沒想明白如何去限制每個數只能做一次階乘,目前的想法是使用乙個狀態陣列status[v][m]記錄達到總和v時有沒有對l[i]做階乘運算,如果已經做了階乘,g[v,m]就不能從g[v-l[i]!][m-1]得到。最後本題的答案就是sum(g[s][:])。
以下是具體python**:
def cal(num):
#計算階乘
res = num
for i in range(num-1, 1, -1):
res *= i
return res
while true:
try:
n, m, s = list(map(int, input().split())
l = list(map(int, input().split())
g = [[0 for _ in range(m+1)] for _ in range(s+1)]
g[0][0] = 1
for i in range(n):
#記錄階乘使用情況的陣列status
status = [[0 for _ in range(m+1)] for _ in range(s+1)]
for v in range(s, l[i]-1, -1):
g[v][0] = g[v][0] + g[v-l[i]][0]
for k in range(1, m+1):
g[v][k] = g[v][k] + g[v-l[i]][k]
temp = cal(l[i])
if v-temp>=0 and status[v-temp][k-1]==0:
g[v][k] = g[v][k] + g[v-temp][k-1]
#此處使用了階乘,所以將status[v][k]設定為1
status[v][k] = 1
print (sum(g[s][:]))
except:
break
筆試 位元組跳動2021秋招第一場筆試題目 講解
第一題 某天你得到了乙個長度為n 1 n 500000 的字串,並且這個字串只包含小寫字母。現在允許你修改m 1 m n 個位置的字母,修改完畢你要選取這個字串的乙個連續子串,如果這個子串只包含一種字母,那麼這個連續子串是乙個完美字串。你希望得到的完美字串長度盡可能長,請計算出你所能得到的最長長度是...
indeed秋招筆試第一場
做了indeed秋招的第一場筆試,題目相比別家確實簡單。其中前三道完全是水題,記錄一下 第一題 tabereru 題意 給定乙個字串,遇到 ra 需要刪除,但是刪除之後如果又出現了 ra 那麼不繼續刪除了。即如果輸入是rrraaa,那麼輸出是rraa。思路 字串很短,隨便搞就ok。第二題 matri...
五月月賽第一場總結
總算不是倒數了,還是比較欣慰。但是我發現,最近學了字串演算法,前面的知識忘得厲害。比如c題收集寶石,我很快就看出這是道動規 搜尋,但是我竟然沒有加標記陣列來標記討論過的狀態,然後就陷入了除錯 的死迴圈。好智障。如果加了那個標記陣列,我至少能多拿50分。再比如e題青蛙表演,我也很快看出這是道差分約束,...