7 18 DP考試解題報告

2022-08-02 11:57:11 字數 1784 閱讀 6632

今天的考試真的是天崩地裂,寫了的三個題全炸。。。然而誰叫我弱+不注意細節呢???真的要扇耳光。。。

t1:題意:一段區間的高度為這個區間中高度的最小值,給定n個寬度,求每個寬度的期望高度

40% :算出長度為x的區間的所有的最小值的取值的和,除以總的方案數(n-x+1),用st表預處理可以n^2;(記得開long long)

100%:對於每個點求出他取最小值的區間,即用兩遍單調棧求出左,右邊第乙個小於他的值。。。記為l[i],和r[i],這一步和影魔很像;

對於當前這乙個點,考慮以他為最小值,能貢獻給多少個區間。。。

記l1=i-l[i]+1,l2=r[i]-i+1;

對於長度l在[1,min(l1,l2)]的區間,可以貢獻l*a[i];

對於長度l在[min(l1,l2)+1,max(l1,l2)],可以貢獻min(l1,l2)*a[i];

對於長度l在[max(l1,l2)+1,r[i]-l[i]+1],可以貢獻(r[i]-l[i]+1-l+1)*a[i];

(算對長度為l的區間的貢獻就是看長度為l的區間在[l[i],r[i]]內移動能包含i點多少次);

然後涉及多次修改和一次詢問,考慮序列差分。。。然而這是乙個優秀的差分。。。

發現修改有兩種,乙個是一段區間加上相同的值,另乙個是和每個點本身的長度有關。。。

所以建兩個差分陣列,乙個記錄正常的差分,乙個記錄l前的係數,這樣第三個情況需要拆成兩個修改來維護。。。

其實說了這麼多,**還是很短的。。。

// made by qt666

#include#include#include#include#include#define int long long

using namespace std;

typedef long long ll;

const int n=2000000;

int gi()

int n,m,a[n],q[n],tail,l[n],r[n],ans[n],cf1[n],cf2[n];

main()

tail=0;q[++tail]=n+1;

for(int i=n;i>=1;i--)

ans+=life[i]*v[i];q[++tail]=i;

}printf("%lld\n",ans);

} return 0;

}

t3:棄坑了。。。

t4:題意:關路燈,見codevs。。。

我真的是太弱了,這種dp都打不出來。。。

dp[i][j][0]表示關完了區間[i,j]的燈,然後在區間的左端點的最少花費。。。

dp[i][j][1]表示關完了區間[i,j]的燈,然後在區間的右端點的最少花費。。。

然後用功率的字首和表示其他區間的能耗情況。。。

然後轉移就是4種:

從左到左,從右到左,從右到右,從左到右。。。每次至移動一位來轉移。。。

// made by qt666

#include#include#include#include#define rg register

#define min(a,b) (a'9') ch=getchar();

while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();

return x;

}ll d[n],w[n],dp[n][n][2];

int main()

printf("%lld",min(dp[1][n][0],dp[1][n][1]));

return 0;

}

DP 2479解題報告

考查點 動態規劃 思路 題目的意思實質是要從乙個包含n個整數的集合中選取兩個不相交的子集,在選取的所有方案中,找出兩個子集和的最大值。為此,可以對輸入陣列進行兩個方向的掃瞄。在正向掃瞄時,進行一次0 n 的dp,用dp1 i 表示前i個數中連續和的最大值,反相掃瞄類似。最後從k 0到k n 2進行遍...

Noip模擬考試6 解題報告

peter喜歡玩陣列。noip這天,他從jason手裡得到了大小為n的乙個正整數 陣列。peter求出了這個陣列的所有子段和,並將這n n 1 2個數降序排序,他想 知道前k個數是什麼。不難想到,從最大欄位和向下更新。用set實現 介紹一下set 用法與priority queue基本相同,區別是,...

整數劃分解題報告(DP方法)

1.問題描述 給定乙個正整數n和k 1.將n劃分成若干正整數之和的劃分數。2.將n劃分成k個正整數之和的劃分數。3.將n劃分成最大數不超過k的劃分數。4.將n劃分成若干奇正整數之和的劃分數。5.將n劃分成若干不同整數之和的劃分數。2.問題分類 總的來說這些都是揹包問題 第乙個問 就是乙個完全揹包,揹...