time limit: 10 sec memory limit: 128 mb
submit: 473 solved: 292
[submit][status]
箱子再分配問題需要解決如下問題:
(1)一共有n個物品,堆成m堆。
(2)所有物品都是一樣的,但是它們有不同的優先順序。
(3)你只能夠移動某堆中位於頂端的物品。
(4)你可以把任意一堆中位於頂端的物品移動到其它某堆的頂端。若此物品是當前所有物品中優先順序最高的,可以直接將之刪除而不用移動。
(5)求出將所有物品刪除所需的最小步數。刪除操作不計入步數之中。
(6)只是乙個比較難解決的問題,這裡你只需要解決乙個比較簡單的版本:
不會有兩個物品有著相同的優先順序,且m=2
第一行是包含兩個整數n1,n2分別表示兩堆物品的個數。
接下來有n1行整數按照從頂到底的順序分別給出了第一堆物品中的優先順序,數字越大,優先順序越高。
再接下來的n2行按照同樣的格式給出了第二堆物品的優先順序。
對於每個資料,請輸出乙個整數,即最小移動步數。
3 3145
2736
1<=n1+n2<=100000
題解:看了好久才理解題意,語文是有多爛 囧
維護兩顆splay,然後發現我們每次需要把最大值弄到堆首,然後把它上面的翻轉之後接到另一堆上。
有點兒難寫。。。去膜拜題解。。
orz!我們把兩個接到一塊,乙個指標表示分割處,然後分隔處的移動的o(1)的,而且計算代價也是logn
orz!
**:
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #includeview code10 #include11 #include
12#define inf 1000000000
13#define maxn 100000+100
14#define maxm 500+100
15#define eps 1e-10
16#define ll long long
17#define pa pair18
#define for0(i,n) for(int i=0;i<=(n);i++)
19#define for1(i,n) for(int i=1;i<=(n);i++)
20#define for2(i,x,y) for(int i=(x);i<=(y);i++)
21#define for3(i,x,y) for(int i=(x);i>=(y);i--)
22#define mod 1000000007
23using
namespace
std;
24 inline int
read()
2528
while(ch>='
0'&&ch<='9')
29return x*f;30}
31int
n,m,a[maxn],b[maxn],s[maxn];
32 inline void add(int x,int
y)33
36 inline int sum(int
x)37
42 inline bool cmp(int x,int y)
43int
main()
4458 cout
59return0;
60 }
BZOJ3192 JLOI2013 刪除物品
原題位址 自己想的奇葩做法 對於乙個優先順序為x的物品,考察該物品下方優先順序大於x物品的優先順序被分成了多少個連續段 舉個例子,如x 4,該物品下方物品的優先順序有5,6,7,9,10,13,14,19,則段數為4 則該物品需要被移動的次數k 段數 2 優先順序為x 1的物品在該物品下方?1 0 ...
bzoj 3192 JLOI2013 刪除物品
因為只有兩堆,所以方案數顯然唯一。可以將兩隊合併成乙個陣列,用樹狀陣列維護,每次刪乙個點的代價就是最大值到次大值得距離。一開始假裝兩堆中間有個無限大的數。有點坑點,裡有注釋。code include include include include include include define ll ...
bzoj3192 JLOI2013 刪除物品
description 箱子再分配問題需要解決如下問題 1 一共有n個物品,堆成m堆。2 所有物品都是一樣的,但是它們有不同的優先順序。3 你只能夠移動某堆中位於頂端的物品。4 你可以把任意一堆中位於頂端的物品移動到其它某堆的頂端。若此物品是當前所有物品中優先順序最高的,可以直接將之刪除而不用移動。...