**題目傳送門
首先,我先確定一下暴力是怎麼做的。
我在考場上做的暴力是使用dfs所做的,時間複雜度高到要爆。
但是我這個蒟蒻還是用了。
最終得分50。
可是我還想ac啊,怎麼辦呢,那麼我就請教了dalao們,他們說:
我諤諤,你連dp+二進位制都做不出來嗎?
\color\boxed\texttt}
我諤諤,你連
dp+二進位制都做不出來嗎?
原來這道題是dp+二進位制的方法,我先想出來了暴力的多重揹包,它的時間複雜度是o(n
×w×k
)o(n \times w \times k)
o(n×w×
k),w
ww就是該題中t
it_i
ti的最大值,k
kk即為題中的a
ia_i
ai。總時間複雜度是200
×1000
×50000=1
010
200 \times 1000 \times 50000=10^
200×10
00×5
0000
=101
0,肯定是爆掉了。
那該怎麼辦呢?
之前我們把多重揹包拆成 a
ia_i
ai 個 01 揹包,我們要優化這種拆分方法。我們的目的是表示 [1,
ai
][1,a_i]
[1,ai
] 的所有數。逐個拆分顯然可行,但二進位制拆分更優。設 2p≤
ai≤2
p+
12^p \le a_i \le 2^
2p≤ai
≤2p+
1,那麼我們只需要拆出20,
21,2
2…2p
,ai−
2p
2^0,2^1,2^2 \dots 2^p,a_i-2^p
20,21,
22…2
p,ai
−2p
這些數,也能表示 [1,
ai
][1,a_i]
[1,ai
] 的所有數。那麼,之前列舉 a
ia_i
ai 的迴圈現在只用列舉 [1,
p]
[1,p]
[1,p
],p 是 loga
i\log a_i
logai
級別的。至此,總複雜度為o(n
×w
×loga
i)
o(n\times w\times \log a_i)
o(n×w×
logai
),憑藉揹包優秀的常數,可以ac這道題!
(dfs暴力解法以及暴力多重揹包解法就不給了)
正解**:
(ps:**中有快讀,如過您不知道的話,請看我的blog:c++快讀)
#include
using
namespace std;
#define ll long long
const
int maxm=
500000
;int
read()
//快讀
while
(isdigit
(ch)
)return x*f;
}int n,m;
int dp[
500000+5
];//dp
intmain()
}else
}int zhi=w*k;
for(
int j=maxm;j>=zhi;j--
)//剩下的還要打個包
}for
(int i=
1;i<=m;i++
)return0;
}
NOI Online 3 入門組題解
洛谷傳送門 第一題還是一如既往的水233 沒什麼好說的。統計每一條訊號。對於乙個訊號,統計sos的數量,方法就是列舉每乙個長度為3的區間,如果這個區間是 sos 那麼就統計進去。取最大數量。有乙個小坑,就是最大可能有多個,要用vector儲存。include using namespace std ...
NOI Online 3 提高組 水壺
在乙個長度為 n 的序列中求出長度為 k 1 的最大子段。本題唯一的需要注意的一點是當 k n 時要輸出所有數的和,像我的考場 scanf d d n,k k if k n k n for int i 1 i n i scanf d a i for int i 1 i k i op a i for ...
NOI Online 3 入門組 第二題 觀星
題目傳送門 bfs和dfs的簡單題目,在這我只講bfs。我們先找到乙個 然後對其進行 bfs,並將所有訪問過的 標記為 在進行 bfs 的同時記錄下目前的 數量。當一次 bfs 結束後,我們將統計的數量放入之前開好的桶中,即將 hre s 1h 1 hres 1。如果此時 hre sh hres 為...