Digital DP Study Notes

Digital DP as the name suggests is to engage in digital DP QAQ

The reason why the concept of digits is introduced is entirely for dp. The essence of digital dp is to change a violent enumeration method, so that the new enumeration method meets the properties of dp, and then memorize it.

The DP state is mostly represented by dp[pos][.........], where POS represents the number of digits, ... is the different limit of different topics, dp[][] is generally number of storage plans

The state transition enumerates the state of each bit according to the title and DP properties, and then stores the sum of all states in the pos bit

Then you'll think like it's not quite right 

Different sets of data on the same topic may have different restrictions. At this time, when the pos bit is enumerated, calling dp[pos] directly will cause an error

how to do QAQ

Thinking about bringing these limitations in memoized search

This gives rise to two sluts, limit and lead.

Where limit represents the maximum range you can enumerate

For example, if you want to enumerate the numbers from 0 to 216

If you enumerate 2 first, then the maximum range is reached (limit=1)

Then you can only choose 0 and 1 for the second digit

If your first enumeration is 1 (limit=0)

Then you can choose the next digit from 0 to 9 (19X must be smaller than 2XX)

lead means that the binary digits before pos are all 0 (that is, leading zeros)

Under some conditions, leading zeros will have an impact on DP

So transfer this state when searching

The template is as follows

inline int dfs(int pos,int XXX,bool lead,bool limit){
	if (pos==-1)return XXX;//All digits have been enumerated
	if (!lead&&!limit&&dp[pos][XXX]!=-1)return dp[pos][XXX];//记忆化
	int ans=0;
	int up= limit? a[pos]:X;
	for (int i=0;i<=up;i++){//Enumerate all possibilities of the current digit
		if (lead&&i==0)ans+=dfs(pos-1,XXX,lead,limit & (i==a[pos]));//Handle leading zeros
		else ans+=dfs(pos-1,dp transfer,0,limit & (i==a[pos]));// process limit::limit & (i==a[pos])
	}
	if (!limit&&!lead)dp[pos][sta]=ans;//Memoization
	return ans;
}
inline int solve(int x){
	int pos=0;
	while (x){
		a[pos++]=x&1;//Disassemble the maximum range on each bit
		x>>=1;
	}
	return dfs(pos-1,XXX,1,1);//Here lead and limit must be 1 QAQ perceptually
}

Some notes (Konjac considers some tricks QAQ):

~~~~~~ Enumerate from a to b, can be processed as 0 to b minus 0 to (a-1)

~~~~~memset(dp,-1,sizeof(dp))

~~~~~~ Some summations can be converted to arithmetic differences

~~~~~ The value in dp[pos] is generally an inherent attribute of the number rather than some restrictive attributes on the question (this is a point to be considered when doing the question even if the nature is)

That's it (it should be)



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324441240&siteId=291194637