思路code
lichking 希望收集**的黑暗力量,並依靠它稱霸世界。
世間的黑暗力量被描述成乙個長度為n 的非負整數序列,每次它可以選擇這個序列中的兩個相鄰的正整數,讓他們的值同時減一併獲得一點**力量,直到不存在滿足條件的數。
然而你不希望他能夠得逞,所以你會使得他收集的能量盡可能少。
na1 a2 … an
輸出一行乙個整數,表示答案。
這題可以考慮用dp來做。
設f
if_i
fi表示i
ii這個位置要取完且1
11~i
ii都合法。
因為是兩個連續的數,所以可以考慮從三個位置轉移。
1.f i−
1f_fi−1
轉移。由於要將連續兩個取完,即fi=
fi−1
+aif_i=f_+a_i
fi=fi
−1+
ai。
2.f i−
2f_fi−2
轉移。表示空乙個取,即fi=
fi−2
+aif_i=f_+a_i
fi=fi
−2+
ai。
3.f i−
3f_fi−3
轉移。表示空兩個取,即fi=
fi−3
+max
(ai−
1,ai
)f_i=f_+max(a_,a_i)
fi=fi
−3+
max(
ai−1
,ai
)。因為必須i和i-1都取完,才能夠保證i-2和i-1不連著。
將上述轉移式整合一下,就可得
f i=
min(
min(
fi−1
+ai,
fi−2
+ai)
,fi−
3+ma
x(ai
−1,a
i))f_i=min(min(f_+a_i,f_+a_i),f_+max(a_,a_i))
fi=mi
n(mi
n(fi
−1+
ai,
fi−2
+ai
),f
i−3
+max
(ai−
1,a
i))
但你會發現一些interesting的問題
如:……4 3 6 2……,當執行到6時,你會發現不可能取6個,最多只能取5個,那會不會影響答案呢?
並不會,因為錯誤的計算算出來的答案會多,自然會比正確情況的答案多,而正解又包含在我們推導的三個情況裡,所以正解會篩掉錯誤的計算。
#include
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define min(a,b) ((a)
#define max(a,b) ((a)>(b)?(a):(b))
int n,a[
100005
],f[
100005];
intmain()
NOIP2017提高A組集訓10 21 總結
今天和學軍 雅禮的dalao們一起切磋,感覺他們太強了。接到題目 t1 一定存在著什麼規律。於是我後來打了個表找了一下規律 顯然 部分大佬們想到t1的部分分的dp 強 t2 一看就知道很可能是dp。我dp很爛,所以先打30分暴力再說。打完之後去想60分。我又根據暴力發現了在遞增序列裡,剩下的後面的數...
NOIP2017提高A組集訓10 30 總結
今天幹了些什麼 看到第一題,我蒙b了 感覺這題之前在 見過,記得好像是將圖斜過來看還是怎樣的。於是去看第二題。第二題乙個很顯然的做法,將邊排序,然後暴力建mst。然而我將時間複雜度多算了乙個0,以為不能過,結果我多加了乙個用來騙分的東西,結果這個騙分的東西打錯了,要騙分的那兩個資料都沒過。55555...
NOIP2017提高A組集訓10 22 幸運值
校慶志願者小z在休息時間和同學們玩卡牌遊戲。一共有n張卡牌,每張卡牌上有乙個數ai,每次可以從中選出k張卡牌。一種選取方案的幸運值為這k張卡牌上數的異或和。小z想知道所有選取方案的幸運值之和除以998244353的餘數。輸入的第一行有兩個整數n和k。第二行有n個整數,表示序列a。乙個整數表示答案。輸...