求區間[a,
b]
[a,b]
[a,b
]有多少個數是「完美的」。
乙個數是「完美的」,當且僅當這個數的各位能分成兩個集合,使得兩個集合中數字的和相等。
b ≤1
09
b\leq 10^9
b≤10
9其實思考這題的時候已經沒有什麼時間了。
但我還是努力地去想正解。
看到的第一眼就會想到數字dp,然後腦中就彈出了乙個dp狀態。
很快就被自己證偽了,因為顯然有重複。
想其它做法,卻一直搞不出來。
看時間真的不多了,於是就去打暴力。
思想特別簡單,列舉[a,
b]
[a,b]
[a,b
]中的數,然後判斷它們是否可行。
最容易想到的是揹包,但是我認為揹包會**,於是我打了折半搜尋。
然後又搞了各種優化……
最終成功水到了50分。
大把人是打表過的,我真是醉了……
50分的107
10^7
107資料範圍其實有另一種更簡單的方法:還是揹包,但由於揹包的值為0
00或1
11,範圍就在[0,
45]
[0,45]
[0,45]
,就可以用乙個long long
將dp陣列壓起來,轉移的時候直接位運算搞定……
ymq說,數字dp一般都會開到1018
10^10
18,這題只開到109
10^9
109,不是可以打表嗎?
接下來介紹一下分段打表**:
將[ 1,
106x
][1,10^6x]
[1,106
x](其中1≤x
≤103
1\leq x\leq 10^3
1≤x≤10
3)的答案全部跑出來。
這樣,在詢問中一大段的區間就不用處理了,只需要暴力處理剩下的106
10^6
106個數……
時間還快得很……
這題用傳統的數字dp似乎不太好做,尤其是判斷重複,更加繁瑣。
於是我們就試著換乙個角度,逃避重複的問題。
可以列舉組成數字的各位數分別有哪些。如果這些數能組成「完美的數」,就進行排列,將範圍之內的數統計如答案。
這樣顯然就不用怕重複了,因為如果是平常的做法,各位數可能有多種組成和相等的兩個集合的方法。但是這樣不需要管有多少中方法,只要它是成功的就對了。
有重複元素的排列有個公式:(∑n
umi)
!∏nu
mi
!\frac
∏numi
!(∑n
umi
)!不會證……noip初賽的資料上的……
列舉出來的東西不會太多,具體是多少,其實我也沒有統計……鄭姐說是40000
40000
4000
0到80000
80000
80000。
判斷它們是否可以組成「完美的數」就用上面說的那個二進位制優化揹包的方法。
然後統計答案的時候像正常的數字dp一樣卡著它的上限,如果當前位選的數小於邊界,後面的就可以隨便選,用公式算就好了。
所以這題還算是個數字dp吧……這是數字dp的特徵啊……
using
namespace std;
#include
#include
#include
int pow10[10]
,fac[10]
;int low,up,w;
int lim;
int num[10]
;int ans;
inline
boolok(
)return
((s&1^
1)&&(f>>
(s>>1)
&1))
;}inline
intcalc
(int m)
inline
void
dfs(
int p)
if(num[th]
&& p)
}void
find
(int k,
int s)
if(k>9)
return
;for
(int i=
0;i<=w-s;
++i)
num[k]=0
;}intget_ans
(int x)
intmain()
在遇到會出現重複的問題是,可以試著換個角度,避免重複。
JZOJ3360 NOI2013模擬 蘋果樹
傳送門 神犇家門口種了一棵蘋果樹。蘋果樹作為一棵樹,當然是呈樹狀結構,每根樹枝連線兩個蘋果,每個蘋果都可以沿著一條由樹枝構成的路徑連到樹根,而且這樣的路徑只存在一條。由於這棵蘋果樹是神犇種的,所以蘋果都發生了變異,變成了各種各樣的顏色。我們用乙個1到n之間的正整數來表示一種顏色。樹上一共有n個蘋果。...
NOI2013 矩陣遊戲
據學長的話來說 這是當年noi最簡單的一道題 於是抱著試一試的心態做了一做 蒟蒻qaq 由於矩陣乘法不會,只能數學必修的種數列知識推公式 先橫向推 f x k a f x 1 k 展開就可以得到乙個等比數列 然後根據等比數列的性質可得 fx ax 1 f1 b ax 1 1 a 1 至此我們完成了將...
NOI2013矩陣遊戲
題目鏈結luogu1397矩陣遊戲 題目大意 已知 f1 1 1 fi,j a f i,j 1 bf i,1 c fi 1,m d j 1 i 1 求f n,m 我們可以構造矩陣 1 fn,1 1 0ba m 1 1fn m 1 c fn 1,m d 10b a m 1 1 fn,m 令t 10ba...