4.10考試(過程)
阿新 • • 發佈:2022-04-10
上來看到problem1,想到了之前比賽做過的“遊戲”問題,這兩個題何其相似。
第一時間想考慮貪心,推了一會兒,發現這個題的不適用貪心策略(即使可能有這樣的策略,判斷也過於複雜)
不貪了,搜尋
寫到一半,想了想一些特殊判斷剪枝,n與k均為正數,k小於n的情況下方法沒得選,只能不斷-1,於是把它加在前面了:
if(k<n) printf("%d\n",n-k),exit(0);
寫搜尋的時候也卡了一會,因為一開始想用一個變數ans記錄,不現實啊!應該用陣列記錄到達某個點的步數。
problem2:單調序列,先找了找幾個特點:
第一,不上升和不下降兩個都要考慮;
第二,目標未知;
第三,要求最小改變數,而不是最小改變次數。
由第三點就知道肯定要動態規劃來做,但是目標未知!
所以思考了一下,最優策略下改變結果一定都是原序列有的數
比如1 3 2 4 5 3 9 -->1 3 3 4 5 5 9,其中設b[]={1,2,3,4,5,9}作為目標陣列。
然後就要考慮怎麼dp了,這段最費時間,不過好在能夠解決第一點(不上升和不下降,改變dp順序即可)
然後開始寫,中間還是要注意初始化。
int dp(){ memset(f,0x5f,sizeof(f)); memset(f[0],0,sizeof(f[0])); FOR(i,1,n){ FOR(j,0,m){ f[i][j]= min(f[i][j-1],f[i-1][j]+abs(a[i]-b[j])); } } int ans = f[n][m]; //正反搜兩次 memset(f,0x5f,sizeof(f)); FOR(i,1,n){ ROF(j,m,0){ f[i][j] = min(f[i][j-1],f[i-1][j]+abs(a[i]-b[j])); } } ans = min(ans,f[n][m]); return ans; }
problem3,一眼看出來是樹狀陣列/線段樹問題。
(大樣例的億點問題好像對我沒影響,能正常輸出不知為什麼)
兩個操作是區間修改+區間查詢?(這個超出我能力範圍,但是勉強寫了個單點查詢+迴圈,可能超時)
先寫了前面的樹狀陣列一些基本函式(忘得差不多了)
然後才想起來要用b[i]=a[i]-a[i-1]來構成陣列。
判斷大於c的部分,卡了40分鐘左右,後面就寫暴力提交了。