《吉林大學ACM集訓隊選拔賽》

2022-06-19 20:15:10 字數 3069 閱讀 1367

a:

數字dp。

dp[i]表示從小到大第i位時的貢獻。

可以發現。

當第i位為7時。它的貢獻即為(i+1~n)*10.

即70.71,72,73,74,75,76,77,78,79.對於每一位都有10個數。

0~10有10個.

0~100有100個.

所以可以預處理出這個數。

顯然可以發現,當該位沒有到達上界時,下面的位任意組合都可以在它的範圍內.

比如當前位上界為7,當前值為6.

60,61,62,63,64,65,66,67,68,69.

601,601,...

610...

690...

這些都是可以的。顯然這個數是0~(10^(i-1)).即10^(i-1)個數.

當當前位為上界時,就需要額外統計。

所以我們的dp[i]就只需要存不是上界時,下一位的總貢獻,因為對於當前位都可以湊得.

當當前位為7時,和下面的位的組合都會有1的貢獻。

那麼當加上下面位自身的貢獻後,顯然要加上7的貢獻,這個值顯然是7*(10^(i-1)).

這裡由於後面能夠湊得的數字組合個數不一定是全部10^i(因為有上界的影響)。

所以在dfs過程中返回值用pii.來存下一位的方案數和下一位能湊成的個數

如果我們用dp[0]來表示最高位的情況。

然後dp[1]..dp[2]來遞推。

最後對於當前數字顯然是對的。

當是當字串長度改變時,顯然答案就不再正確。

因為這時會直接沿用dp[1]..dp[2]..

但當前字串的最高位的dp[1]顯然和之前的不一樣.

所以我們應該用dp[0]來存最低位的無上界情況,顯然大家的最低位的情況都是一樣的.

code:

#includeusing

namespace

std;

typedef

long

long

ll;//

typedef pairpii;

const

int n = 1e5+5

;const

int m = 1e6+5

;const

int mod = 1e9+7

;#define pi acos(-1)

#define inf 1e18

#define inm int_min

#define rg register

#define pb(a) push_back(a)

#define mk(a,b) make_pair(a,b)

#define dbg(x) cout << "now this num is " << x << endl;

#define met0(axx) memset(axx,0,sizeof(axx));

#define metf(axx) memset(axx,-1,sizeof(axx));

#define sd(ax) scanf("%d",&ax)

#define sld(ax) scanf("%lld",&ax)

#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)

#define sdd(ax,bx) scanf("%d %d",&ax,&bx)

#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)

#define sfd(ax) scanf("%lf",&ax)

#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)

#define pr(a) printf("%d\n",a)

#define plr(a) printf("%lld\n",a)

/*數字dp。

dp[i]表示從小到大第i位時的貢獻。

可以發現。

當第i位為7時。它的貢獻即為(i+1~n)*10.

即70.71,72,73,74,75,76,77,78,79.對於每一位都有10個數。

0~10有10個.

0~100有100個.

所以可以預處理出這個數。

顯然可以發現,當該位沒有到達上界時,下面的位任意組合都可以在它的範圍內.

比如當前位上界為7,當前值為6.

60,61,62,63,64,65,66,67,68,69.

601,601,...

610...

690...

這些都是可以的。顯然這個數是0~(10^(i-1)).即10^(i-1)個數.

當當前位為上界時,就需要額外統計。

所以我們的dp[i]就只需要存不是上界時,下一位的總貢獻,因為對於當前位都可以湊得.

當當前位為7時,和下面的位的組合都會有1的貢獻。

那麼當加上下面位自身的貢獻後,顯然要加上7的貢獻,這個值顯然是7*(10^(i-1)).

這裡由於後面能夠湊得的數字組合個數不一定是全部10^i(因為有上界的影響)。

所以在dfs過程中返回值用pii.來存下一位的方案數和下一位能湊成的個數

如果我們用dp[0]來表示最高位的情況。

然後dp[1]..dp[2]來遞推。

最後對於當前數字顯然是對的。

當是當字串長度改變時,顯然答案就不再正確。

因為這時會直接沿用dp[1]..dp[2]..

但當前字串的最高位的dp[1]顯然和之前的不一樣.

所以我們應該用dp[1]來存最低位的無上界情況,顯然大家的最低位的情況都是一樣的.

*/string

s;ll dp[n],pre[n];

typedef pair

pii;

intn;

void

init()

pii dfs(

int pos,bool f)//

pos-當前位,f-前驅是否為上界

if(!f) dp[n-1-pos] =ans;

return

pii(ans,cnt);

}void

run()

} int

main()

view code

ACM集訓隊第一周

字首和計算可以減少時間複雜度,提高執行速度 對於求每一項均是前幾項總和的情況下的部分幾項和或者某一單項的時候使用 一般寫成ans i ans i 1 a i eof即是end of file的縮寫 eof表示檔案結尾,eof 表示檔案還沒有結束。用於多組 不定組 資料輸入時 如 while scan...

吉林大學CSDN高校俱樂部2012納新

一 是發展會員,擴大影響力,即增大基數,讓更多的同學了解csdn,了解技術,降低門檻,讓有興趣的同學敢於嘗試,有勇氣從頭學起,增加自信,就是那條格言 天下沒有學不會的技術!我們最看重的不是你現在的水平如何,而是你的態度和潛力,自己要問問自己是不是真的有興趣,想做好。二 是選拔核心會員 有些同學計算機...

吉林大學967 高階語言程式設計 2010

2010 1 對輸入的正整數,求和的約數和。如 18的約數和為 1 2 3 6 9 18 39 include includeint main else printf d add system pause return 0 2010 2 設2000以內的素數序列 從小到大 為 x1,x2 編寫一程式...