BSOJ3299 洛谷P1874 快速求和

2021-07-24 06:59:50 字數 2070 閱讀 7863

3299 -- 【模擬試題】快速求和

description

給定乙個數字字串,用最少次數的加法讓字串等於乙個給定的目標數字。每次加法就是在字串的某個位置插入乙個加號。在需要的所有加號都插入後,就象做普通加法那樣來求值。

例如,考慮字串"12",做0次加法,我們得到數字12。如果插入1個加號,我們得到3。因此,這個例子中,最少用1次加法就得到數字3。

再舉一例,考慮字串"303"和目標數字6,最佳方法不是"3+0+3",而是"3+03"。能這樣做是因為1個數的前導0不會改變它的大小。

寫乙個程式來實現這個演算法。

input

第1行:1個字串s(1<= s的長度 <= 40) 和1個整數n。s和n用1個空格分隔。

output

第1行:1個整數k,表示最少的加法次數讓s等於n。如果怎麼做都不能讓s等於n,則輸出-1。

sample input

2222 8

sample output3

hint

【資料範圍】

0 ≤ n ≤ 100 000

0 ≤ s ≤ 40

乍一看這道題,該怎麼做呢,搜尋還是dp,似乎都很好想。

搜尋看上去是要tle的(這樣最多就有2^39種可能性

),那麼有沒有什麼優秀的剪枝呢?

容易想到也容易實現的剪枝有如下三個:

仍需注意的是,無論是搜尋還是dp,由於s的長度有40位,而 n ≤ 100 000,那麼在預處理g[i][j](i到j的值時),我們將大於100000的設為inf即可。

那麼dp也還是比較簡單的,運用了一些揹包的思想的分配類動規,f[i][j]表示我前i個數的累計sum為j,但是這個時候我們發現,同搜尋一樣,我們需要知道最後乙個加號的位置才能進行轉移,所以我們可以顯而易見的知道這是乙個模板,列舉最後乙個加號的位置(也就是將前i個數分開的點,分配類動規之本意),但是在寫方程時我們也許會遇到一些麻煩,因為我們發現我們不知道前面乙個數是否是合法的,所以定義如下:

bool f[maxlength+5][maxvalue+5];//前i個數字加+號能否構成j值

int rec[maxlength+5][maxvalue+5];//前i個數字構成j值需最少加號數

**在下面:

#include#include#include#include#include#define inf 0x3fffffff

using namespace std;

string s;

int g[105][105],last,n,l,ans=inf;

void dfs(int pos,int last,int p,int sum)//pos 當前位置, last 上乙個加號的位置, p 加號位置, sum,總和

dfs(pos+1,last,p,sum);

dfs(pos+1,pos,p+1,sum+g[last+1][pos]);

}int main()

dfs(1,0,0,0);

if(ans==inf)cout<<-1;

else cout<#include#include#include#include#define inf 100005

using namespace std;

string s;

int g[105][105],n,l,rec[55][100005],f[55][100005];

int main()

for(int i=0;i<=l;i++)

for(int j=0;j<=n;j++)

rec[i][j]=inf;

rec[0][0]=0,f[0][0]=1;

for(int i=1;i<=l;i++)

for(int j=1;j<=i;j++)

}if(rec[l][n]==inf)cout<<-1;

else cout

}

洛谷P3806 BSOJ1113(點分治)

一棵n個點的帶權有根樹,有p個詢問,每次詢問樹中是否存在一條長度為len的路徑,如果是,輸出yes否輸出no.第一行兩個整數n,p分別表示點的個數和詢問的個數 接下來n 1行每行三個數x,y,c,表示有一條樹邊x y,長度為c 接下來p行每行乙個數len,表示詢問樹中是否存在一條長度為len的路徑 ...

洛谷 P3372 線段樹 1

今天植樹節,來種一棵線段樹。傳送門如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第 i 個數字表示數列第 i 項的初始值。接下來m行每...

洛谷P3374 樹狀陣列 1

乙個數列,滿足如下操作 給其中乙個數加x 求區間和 數列長度n,運算元m滿足1 n m 500000 1 n,m 500000 1 n m 5 0000 0樹狀陣列基礎支援這兩種操作,核心思想是將 1 i 的整體和分成許多個小的區間和,分割的條件是二進位制拆分。首先介紹乙個lowbit,意思是取到二...