題意:
給出乙個長度為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 ...