【BZOJ-2063】我爸是李剛 數位dp 好題

2063: 我爸是李剛

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 139  Solved: 72
[Submit][Status][Discuss]

Description

背景: LC同窗在2011年的浙江省選中輕鬆虐爆了WJMZBMR,無壓力進入省隊並參加了NOI 2011,在1個小時以後,A光了全部題目的LC同窗輕鬆的喝着茶,哼着小曲。 因爲在信息學方面的傑出表現以及LC同窗的父親是偉大的LG同志。 LC同窗輕鬆得到了2012年諾亞方舟的船票。而且獲得了賣票員這一肥差。 題目描述: 賣票員這一工做十分簡單,世界上有不少賣票員。LC同窗分到了第L號票到第R號票。 由於一些神奇的東西,第I號票對應的船艙能坐的人剛好是I的各位數字之和。 地球上有不少你們族,每一個家族都有M我的,同時每一個家族都想買一些連續的票位使他們家族的人都能坐的上船。 你們族都很排外,不願跟別人共享一張票對應的船艙。 LC同窗想知道他在把票都賣光的狀況下,能 服務幾個你們族呢?php

Input

一行三個數L,R,Mios

Output

一行一個數表示結果。spa

Sample Input

40 218 57

Sample Output

29

HINT

100%的數據 l,r<=10^18 ,M<=1000 50%的數據,r-l<=10^63d

Source

和諧社會模擬賽 Sgu390blog

Solution

詳見 2009年國家集訓隊論文 ,這類題以前真的沒見過,沒啥好說的。ip

Code

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
#define LL long long
#define Pa pair<LL,LL>
#define sum first
#define res second
#define MP make_pair

LL L,R,M;
int dl[19],dr[19],len;

Pa dp[19][210][1010];

Pa operator + (const Pa &A,const Pa &B) {return MP(A.sum+B.sum,B.res);}

inline Pa DP(int dep,LL sum,LL res,bool f,bool g)
{
	if (!dep) return (sum+res>=M? MP(1LL,0LL):MP(0LL,sum+res));
	if (!f && !g && ~dp[dep][sum][res].sum) return dp[dep][sum][res];
	Pa ret=MP(0,res);
	for (int i=(f? dl[dep]:0); i<=(g? dr[dep]:9); i++)
		ret=ret+DP(dep-1,sum+i,ret.res,f && i==dl[dep],g && i==dr[dep]);
	if (!f && !g) dp[dep][sum][res]=ret;
	return ret;
}

int main()
{
	scanf("%lld%lld%lld",&L,&R,&M);
	len=0; while (L) dl[++len]=L%10,L/=10;
	len=0; while (R) dr[++len]=R%10,R/=10;
	for (int i=1; i<=18; i++)
		for (int j=0; j<=200; j++)
			for (int k=0; k<=1000; k++)
				dp[i][j][k]=MP(-1,0);
	printf("%lld\n",DP(len,0,0,1,1).sum);
	return 0;
}
相關文章
相關標籤/搜索