題目神奇的口袋

2022-04-07 07:37:38 字數 1769 閱讀 6681

這個問題在演算法效率一節裡面,是這樣的:

1761:神奇的口袋(2

)檢視 提交 統計 提問

總時間限制: 1000ms 記憶體限制: 65536kb

描述有乙個神奇的口袋,總的容積是400,用這個口袋可以變出一些物品,這些物品的總體積必須是400。john現在有n個想要得到的物品,每個物品的體積分別是a1,a2……an。john可以從這些物品中選擇一些,如果選出的物體的總體積是400,那麼利用這個神奇的口袋,john就可以得到這些物品。現在的問題是,john有多少種不同的選擇物品的方式。

輸入輸入的第一行是正整數n (

1<= n <= 200

),表示不同的物品的數目。接下來的n行,每行有乙個1到400之間的正整數,分別給出a1,a2……an的值。

輸出輸出不同的選擇物品的方式的數目對10000取模的結果(因為結果可能很大,為了避免高精度計算,只要求對10000取模的結果)。

樣例輸入

3200

200200

樣例輸出

3

如果把資料規模都縮小一下,那就是神奇的口袋1,在解這兩個問題的時候,想了幾種方法,其中最慢的一種就是遍歷每種情況——對每乙個都實行:取或不取:

#includeusing

namespace

std;

const

int eval=40

;int n,cnt,*arr;

void search(int depth,int

val)

else

if(val==eval)

else

if(depth>=0)}

intmain()

cnt=0

; search(n-1,0

); cout

<}

這解決小規模資料的問題是可以用的一種直觀做法。當然,也可以用動態規劃。用動態規劃時我們要考慮的就是:取當前數字時,能達到的和k的次數是多少?這樣乙個問題,所以從0開始遞推就可以了,核心部分看起來是這樣的(為什麼倒序後面另一種解法會詳細說明):

f[0]=1

;

for(int i=1;i<=n;i++)

}

那麼為什麼拿出這樣乙個簡單的動態規劃來寫一篇呢?因為這裡還有乙個有趣的解法——把動態規劃的過程展開來,理解起來也不難:我們把每個元素以及和出現的次數放入一排桶裡面,或者說用乙個陣列記錄元素以及和出現的次數(dp),然後:拿出下乙個元素,將非空的桶的編號和該元素的和對應的桶(計數)+1,並且,把該元素對應的桶(計數)+1。這也能達到我們的目的。現在考慮這樣幾個問題:

1、先累加元素自身對應的計數還是先累加全部非空桶的計數。

2、累加元素自身對應的計數時是+1,累加其他元素或和呢?

第乙個問題很容易想到如果先累加自身的,則導致當前元素被多次累加。於是,同理可知,累加其他桶的時候要從大的開始。

第二個問題也很好解答,考慮一下桶裡面的計數是什麼?是這個桶編號所代表的元素或和出現的次數,所以當用這個桶累加時,其結果對應的桶也應該增加這些次數。

好了,實現起來肯定要比上面的動態規劃多一些**:

int dpsearch(int infos,int

infcnt)}}

table[curval]++; }}

return

table[maxv];

}

在我提交的時候這兩種演算法都可以通過,第乙份**時8ms第二份9ms,畢竟都是動態規劃的思想,只是第二個把內部細節展開了一些。

題目1114 神奇的口袋

一題目描述 有乙個神奇的口袋,總的容積是40,用這個口袋可以變出一些物品,這些物品的總體積必須是40。john現在有n個想要得到的物品,每個物品的體積分別是a1,a2 an。john可以從這些物品中選擇一些,如果選出的物體的總體積是40,那麼利用這個神奇的口袋,john就可以得到這些物品。現在的問題...

神奇的口袋

原題 有乙個神奇的口袋,總的容積是40,用這個口袋可以變出一些物品,這些物品的總體積必須是40。john現在有n個想要得到的物品,每個物品的體積分別是a1,a2 an。john可以從這些物品中選擇一些,如果選出的物體的總體積是40,那麼利用這個神奇的口袋,john就可以得到這些物品。現在的問題是,j...

神奇的口袋

時間限制 1 sec 記憶體限制 32 mb 有乙個神奇的口袋,總的容積是40,用這個口袋可以變出一些物品,這些物品的總體積必須是40。john現在有n個想要得到的物品,每個物品的體積分別是a1,a2 an。john可以從這些物品中選擇一些,如果選出的物體的總體積是40,那麼利用這個神奇的口袋,jo...