hysbz - 1799
給出a,b,求出[a,b]中各位數字之和能整除原數的數的個數。sample input
10 19sample output
3hint
【約束條件】1 ≤ a ≤ b ≤ 10^18
約束:乙個數是它自己數字和的倍數,直接dp根本找不到狀態,列舉數字和,因為總就162,然後問題就變成了乙個數%mod=0,mod是列舉的,想想狀態:dp[pos][sum][val],當前pos位上數字和是sum,val就是在算這個數%mod,(從高位算 *10+i),因為我們列舉的數要保證數字和等於mod,還要保證這個數是mod的倍數,很自然就能找到這些狀態,顯然對於每乙個mod,val不能保證狀態唯一,這是你要是想加一維dp[pos][sum][val][mod],記錄每乙個mod的狀態(這裡sum可以用減法,然而val不行,就只能加一維),那你就想太多了,這樣是會超時的(因為狀態太多,記憶化效果不好)。這裡直接對每乙個mod,memset一次就能ac。下面的**還把limit的當做了狀態,因為每次都要初始化,所以能這樣,memset在多組外面是不能這樣的,不過奇葩的,這**,如果不把limit當狀態,還是在!limit 條件下記錄dp,提交一發,時間竟然更短了,可能是每次memset的關係!!!
——引自wust_wenhao
#include#includeusing
namespace
std;
typedef
long
long
ll;const
int n=18+2,m=162+1
;ll a[n],dp[n][m][m][2];
ll dfs(
int pos,int sum,int val,int mod,bool
limit)
return dp[pos][sum][val][limit]=ans;
}ll solve(ll x)
return
ans;
}int
main()
return0;
}
BZOJ 1799 self 同類分布
給出a,b,求出 a,b 中各位數字之和能整除原數的數的個數。10 19 約束條件 1 a b 10 18 思路 數字dp,dp i j k 的i表示第i位,j表示當前餘數,k表示第i位之前的每一位數字的和。for int i 1 i pos 9 i 中的pos 9是每一位數字的和的最大值。incl...
BZOJ 1799 self 同類分布
bzoj 1799 傳送門 一句話的題目,看得爽,做得煩 一般這類和數字相關的都是數字 dp 吧 不過一開始還是感覺不太可做,畢竟每個數模數不同 但要發現,模數最高也只可能為 9 19 171 於是只要將數按照他們的數字和 即模數 分類計算即可 這樣便暴力解決了模數不同的問題 設 dp sp sum...
bzoj1799同類分布 數字DP
題目 數字dp。1 迴圈方法 預處理出每個位數上,和為某個數,模某個數餘某個數的所有情況 因為開四維會爆空間,所以省去模數,為此需要固定模數一次一次累加 餘數的轉移,以及可以填數的範圍都值得注意。如下 include include include using namespace std typed...