洛谷p1831 數位dp

補充點在其他題解裏面沒有的其他東西。

首先是之所以可以數位dp並且不會算錯的原因是,對於每一個數字,如果這個數字是槓桿數,那麼他的支點有且只有一個,如果一個數字有多個支點,那麼數位dp去枚舉支點就會算重複,算多。

另外全部人都是在說數位dp然後枚舉支點,對R和L-1分別做一次dp,但是可以有個小優化就是,我們要明確一個東西,dp數組存的是那些沒有被限制的的有用數字是數量,也就是對於任意數都適用。

那麼我們可以發現在枚舉支點位置的時候,枚舉位置1,對於R和L-1都分別去dfs了一次,但是實際上所做的效果是一樣的,因爲對於沒有被限制的數字他的數量是不會變的,所以我們可以把兩個數字一起來算,每一次枚舉支點都可以一次性統計。

int solve(int x,int y) {//L, R
	memset(dp, -127, sizeof(dp));
	int pos1 = 0,pos2 = 0;
	while (x) {
		num[1][pos1++] = x % 10;
		x /= 10;
	}
	while (y) {
		num[2][pos2++] = y % 10;
		y /= 10;
	}
	int ans1 = 0,ans2 = 0;
	for (int i = 0; i < 17; i++) {
		ans2 += dfs(pos2 - 1, true, 0, i, 0, 2);
		ans1 += dfs(pos1 - 1, true, 0, i, 0, 1);
	}
	return ans2 - ans1;
}

這是我是solve函數,枚舉所有的支點位置,然後一起統計就可以了,這樣就可以充分的利用之前跑出一遍所獲得的貢獻,在一個另外的點就是,你還可以在開一個維度,那個維度代表的就是你現在枚舉的是哪個支點,就是空間換時間,你就可以不用每次枚舉支點的時候都來一次memset。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章