拖了一年了才補。。。去年現場賽3個小時沒做出來,今年看了半個小時就有思路了= =
有陣列anan
其中aiai
可以作為物品,也可以作為袋子
如果作為物品,aiai
作為物品的重量,不一定要裝在袋子裡
如果作為袋子,aiai
作為袋子的容量,必須要裝滿物品。
對每一組輸入,輸出總的方案數
n
<15,
ai
<
2000
n<15,<2000
n<15
,ai
<20
00乙個合法的最終狀態可以將物品分為幾類:
1.作為物品且沒有放在袋子裡的,即完全沒有考慮的物品
2.作為物品和袋子組成合法袋子
3.作為袋子且裝滿物品
可以用乙個二進位制數表示當前狀態,第i位下標為1表示考慮這個東西(可以作為物品也可以作為狀態),為0表示不考慮這個東西
d p[
sta]
dp[sta]
dp[sta
]表示當前狀態為sta
stast
a時的方案總數.
而乙個合法方案的轉移必定是對於當前sta
stast
a狀態沒有考慮到的東西產生了乙個新的合法的袋子,轉移到了乙個考慮了更多東西的狀態。(新加乙個合法的袋子)
用c nt
[x
]cnt[x]
cnt[x]
表示考慮x狀態的東西作為乙個乙個
乙個合法的袋子的方案數
整個d pdp
dp的轉移過程可以看做是計數01
0101
揹包的轉移過程,先列舉物品,再列舉揹包轉移。注意在列舉揹包的時候一定是當前列舉的乙個合法包的補集的子集,保證物品只會出現在這個合法包中。
設當前考慮的包狀態為i
ii,當前的狀態為j
jj轉移方程如下:
注意不能寫j
>=0
j>=0
j>=0
會死迴圈
#include
using namespace std;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define debug cout<<"****"<#define pb push_back
#define endl '\n'
#define fi first
#define se second
#define db double
#define pii pair
#define mp make_pair
const
int mod=
(int
)1e9+7
;const
int maxn=(1
<<15)
;int n,t;
int a[20]
;int sum[maxn+5]
,dp[maxn+5]
;int cnt[maxn+5]
;//第i位為1表示考慮這個數字,為0表示不考慮當前數字
signed
main()
for(
int i=
0;i<(1
<;i++)}
//cnt[i]表示組成當前狀態的乙個揹包
for(
int i=
0;i<(1
<;i++
)//當前的狀態}}
}for
(int i=
0;i<(1
<;i++
)//當前的袋子
} cout<<]<}return0;
}/*33
1 1 1
51 1 2 2 3
101 2 3 4 5 6 7 8 9 10
*//*7 15 127*/
秦皇島2018CCPC現場賽
所有的磨難挫折,都該慶幸,它來的還不算晚.大海我來了 來之前,就聽說這裡有海,很欣喜.畢竟乙個土生土長的山西人,還沒 看過大海.坐了一夜的火車,下車直奔博維酒店,距離比賽地點特別近,步行10分鐘,搞定了報道,然後就回酒店補覺了.下午ge掉了開幕式,在熱身賽開始前,堪堪來到賽場.熱身賽 cqw和xzw...
2018CCPC秦皇島站(賽後總結)
這大概是我的最後一場acm競賽了,我們長途跋涉來到秦皇島參賽,然而表現的一點兒也不好。9.27號的熱身賽共有四道題,熱身賽估計有點難,第二名也就只做了兩題。我們只做出了一道題,不過第二題我們在比賽結束後,和趙老師討論出了這道題的解法,賽場上我們是用迴圈暴力求解的,複雜度是o n 3 o n o n3...
2018ccpc吉林 C JUSTICE 思維
題意 n個物品,每個物品重量1 2 k i 問可不可以分成兩份,讓這兩份的總量都大於1 2 題解 因為兩份都要大於1 2,那麼我們兩份都找出1 2,剩下的就無所謂了。我們把問題轉化為,兩份都需要找到乙個1,因為 1 2 1 4 1 4,所以乙個1等價於兩個2,4個3.我們先從小到大排個序,令cnt1...