看了網上很多完全揹包的題,都感覺沒解釋清楚。
設包子數為 a1 a2 a3 a4 a5...an
考慮 對於湊乙個 x 數
k1 * a1 + k2*a2 +... +kn*an = x
兩邊mod a1
(k2*a2%a1 +k3*a3%a1 + ... +kn*an%a1 )%a1= x%a1
x%a1 的範圍為 [0,a1);
比如說 想湊 x = 31,a1 = 5; x%a1 = 1;
我能通過 (k2*a2%a1 +k3*a3%a1 + ... +kn*an%a1 )%a1 組合能湊出乙個1
那麼 我只要 將能湊出 1的 (k2*a2%a1 +k3*a3%a1 + ... +kn*an%a1 )%a1組合 再加上5個a[1] , 即可湊出來
但是 有個情況 就是 (k2*a2%a1 +k3*a3%a1 + ... +kn*an%a1 )%a1湊出來的是mod之後的數 可能原這個數為 31 也可能是41 51 . 如果是51的話 那麼31肯定是無法組合的
所以我們用最短路求解
d[i] 表示 湊出 x%a[1] =i 所需要的數最小合
建邊 就是
mp[j][(j+a[i])%a[0]]=min(mp[j][(j+a[i])%a[0]],a[i]);
比如說 對於 a[1] = 5 a[2]=8 a[2]%a[1]=3
那麼 對於 結果餘數為1的情況 , 可以通過加乙個 a[2] 變成餘數為4 所以 1->4有路徑,路徑費用為a[2] = 8;
這樣 一次最短路後 ,
對 i ~ [0,a[1])範圍
如果存在 d[i]=inf 那麼說明這個點不可達 所以 任意 k*a[1]+i (該數mod a[1] = i) 都不能組合 所以此時結果為inf
如果 d[i] = x 那麼 對於任意 x'>x 且 x'%a[1]=i 都可以組合 (x'與x相差整數個a[1],差幾倍補幾倍就行了)
而 對任意 x'#include #include #include #include #define maxn 110
using namespace std;
typedef long long ll;
int mp[maxn][maxn];
int d[maxn];
int v[maxn];
int a[maxn];
const int inf = 0x3fffffff;
int main()}}
for(int i = 0 ; i=inf)
}ll sum = 0;
for(int i = 0 ; iprintf("%d\n",sum);
return 0;
}0s ac
藍橋杯 包子湊數
時間限制 1 sec 記憶體限制 128 mb 提交 20 解決 12 難度 標籤 基礎 提交 狀態 小明幾乎每天早晨都會在一家包子鋪吃早餐。他發現這家包子鋪有n種蒸籠,其中第i種蒸籠恰好能放ai個包子。每種蒸籠都有非常多籠,可以認為是無限籠。每當有顧客想買x個包子,賣包子的大叔就會迅速選出若干籠包...
藍橋杯 包子湊數
time limit 1 sec memory limit 128 mb submit 94 solved 44 submit status web board creator 201440700049 description 小明幾乎每天早晨都會在一家包子鋪吃早餐。他發現這家包子鋪有n種蒸籠,其中...
藍橋杯 包子湊數
小明幾乎每天早晨都會在一家包子鋪吃早餐。他發現這家包子鋪有n種蒸籠,其中第i種蒸籠恰好能放ai個包子。每種蒸籠都有非常多籠,可以認為是無限籠。每當有顧客想買x個包子,賣包子的大叔就會迅速選出若干籠包子來,使得這若干籠中恰好一共有x個包子。比如一共有3種蒸籠,分別能放3 4和5個包子。當顧客想買11個...