貪心 Uva1614奇怪的股市

2021-08-30 17:56:03 字數 1127 閱讀 7780

題意:

給出乙個長度為n的序列a,滿足1<=a[i]<=i,給每個數分配乙個正號或負號,求是否能讓這些數加起來為0,如果是輸出每個數的正負(任意方案)。

題解:如果a陣列每個元素加起來不為2的倍數,就無解

因為正負號不會影響奇偶

若當前沒被判無解,就從後往前掃一遍,記錄乙個sum,如果當前sum<=0,那麼給當前數分配正號,然後sum加上這個數,如果sum>0,分配負號,sum減去這個數。

這樣做一定能保證最終sum為0

證明:設當前掃到了位置i(還未處理i),那麼|sum|<=i+1

考慮數學歸納法

對於i==n,顯然成立

假設這個對於上乙個數來說成立,也就是說,當考慮i+1時,|sum|<=i+2

由於a[i+1]>=1,所以如果sum不為0,那它要麼變號,要麼絕對值減小,如果變號,|sum|也一定<=i

換句話說,我們害怕的情況是|sum|=i+2並且a[i+1]=0,而a[i+1]>=1,所以不會出現這樣的情況

那麼此時最壞的情況是|sum|=0,並且a[i+1]=i+1,此時|sum|=i+1,仍滿足條件,所以結論成立

所以對於位置1,|sum|<=2

此時如果sum=-2,2,0,早就被判無解了

所以sum=1,-1

然後a[i]必須=1

sum就被懟成0了

o(n),很溫和很舒服

**

#include

#include

#define maxn 100006

using

namespace std;

int n,ans[maxn]

,a[maxn]

;int

main()

if(sum==1)

for(

int i=n;i>=

1;i--

)else

}printf

("yes\n");

for(

int i=

1;i<=n;i++

)printf

("%d "

,ans[i]);

printf

("\n");

}}

uva 1614奇怪的股市(歸納法證明,貪心)

輸入乙個長度為n的序列a,滿足 1 le a i le i 要求確定每個數的正負號,使得所有數的總和為0.例如a 則4個數的符號分別是1,1,1,1即可。但若a 則無解。n 1e5。這道題相當於要找到兩堆相等的數。若序列中數的總和為奇數,那麼拆出來的兩堆數無論如何都不可能相等,所以無解。由於這道題的...

UVA12627奇怪的氣球膨脹

找規律。用 f k,i 表示 第 k 小時最上面 i 行有多少紅球。找a b行紅球的數量,也就是求 f k,b f k,a 1 k 時刻的狀態是和 k 1的狀態緊密相關的。k 時刻狀態是 3 個 k 1時刻的狀態 分別位於左上,左下,右上 右下全是藍色球。所以,當 i 2 k 1 等於左上和右上的兩...

遞推 UVA 12627 奇怪的氣球膨脹

題目大意 給你k,a,b,求k小時後,a b行的紅氣球總數。解題思路 求解遞推式即可,只不過注意乙個優先順序問題,符號優先順序高於 兩個符號,所以不能1 1 ac include include include include include include using namespace std ...