2017 3 13 木棍分割 思考記錄

2021-07-28 09:44:12 字數 1423 閱讀 1163

肯定是二分+dp

但只能想出n^2m dp

感覺每個數字的狀態都和前面的數字和有關,但劃分是靈活的,可以衍生出多種字首和的情況。

看了題解,但是:

、、  、一臉懵逼,,**是還pascal的、、   

自己推(meng)理(bi)了乙個上午,終於推出來了:

第一問是二分裸題、

第二問是字首和優化dp

在對n^2m dp的瘋狂優化之後,終於寫出了兩組遞推式:

f[r]=((qqsum[r-1]-qqsum[l-2])%m+m)%m;

qsum[r]=(qsum[r-1]+f[r])%m;

原理:根據傳統區間dp思想,列舉區間的右端點,但由於隨著右端點的不斷增大,左端點一定是單調向右移的

在(左端點 ~ 右端點-1 )這個區間內都是在<=ans內合法的,左端點往左的就是分出的j-1次的方案數;;

我們只需求出 左端點 ~ 右端點-1   的點往左的上乙個劃分的方案數之和 

所以就要用字首和:      右端點的方案數=左端點-1的方案數+左端點的方案數+左端點+1的方案數+左端點+2的方案數+...+右端點-2的方案數+右端點-1的方案數;

=右端點-1的方案數字首和-左端點-2的字首和

大概的流程:

像不像乙隻爬蟲在樹枝上爬?

沒做過這種演算法(其實就沒見過)的題,所以我們是可以利用題目的性質、特點(單調性、邏輯)自己寫出演算法的(甚至有可能創出新的演算法)

演算法競賽的本質就是考驗你的分析能力,並用程式描述你的分析結果

#include#includeusing namespace std;

#define n 50005

#define m 10007

int mid,jishu,a[n],ya,n,m,i,ans1,sum[n],daan,qian[n],qqsum[n],f[n],qsum[n],j,l,r;

bool zai;

int erfen(int l,int r)

}

if(zai)

else r=mid;

} return l;

}int main()

daan+=f[n];

daan%=m;

for(i=1;i<=n;i++)

}printf("%d %d",ans1,daan%m);

}

時間很慢(沒有任何優化,時間應該是  n*3*m的、、)

但bzoj能過,洛谷上過不了,因為時限錯了

%%lych   orz orz

木棍分割 HAOI2008

有n根木棍,第i根木棍的長度為li,n根木棍依次鏈結了一起,總共有n 1個連線處.現在允許你最多砍斷m個連 接處,砍完後n根木棍被分成了很多段,要求滿足總長度最大的一段長度最小,並且輸出有多少種砍的方法使得總長 度最大的一段長度最小.並將結果mod 10007。輸入檔案第一行有2個數n,m.接下來n...

HAOI2008 木棍分割

沒寫過幾道的字首和優化 dp 第一問是小學生難度的二分 第二問就直接 dp 了 設 dp i j 表示當前分割點在 i 之後,前面一共分割了 j 段的方案數 利用字首和單調性,通過二分預處理出每乙個點往前能擴充套件到的最大位置,之後字首和優化就可以啦 但是發現這個樣子空間會炸,而這個樣子還沒有辦法滾...

bzoj1044木棍分割

第一問二分答案 第二問dp需優化空間和時間 坑了一天 才寫出個坑爹坑爹程式 program hehe const q 10007 var ans,s,min,max,n,m,i,j,k,l,t longint sum,h array 0.50000 of longint d array 0.5000...