2020牛客暑期多校训练营(第六场) Harmony Pairs 数位DP

经典数位DP,两个限制条件。

AB同时跑。B由N限制,A由B限制。

然后就变成经典数位DP的题目了。

细节看代码。

还有两个限制最好开到数组里,虽然浪费点空间,但能省好多时间,我就因为这里T了。。

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1000+7;
const int mod=1e9+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
char s[107];
int di[107];
ll nm[1007],sm[1007];
//处理到第i位,前面的已确定的数位中S(a)-S(b)=d    aS(b)的数量 
ll dp[107][2007][2][2];
int p,nd;
ll dfs(int len,int d,bool la,bool lb)//la:a与b的大小关系,lb:b与n的大小关系 
{
	if(len==0)return (d>1000);
	if(~dp[len][d][la][lb])return dp[len][d][la][lb];
	ll cnt=0;
	int upb=lb?di[len]:9,upa;
	for(int i=0;i<=upb;i++)//B当前位的取值
	{
		upa=la?i:9;
		for(int j=0;j<=upa;j++)
		{
			if(j-i+d<1000-(len-1)*9)continue;//不可能构造出正解 
			cnt+=dfs(len-1,d+j-i,la&&j==i,lb&&i==upb),cnt%=mod;
		}
	}
	return dp[len][d][la][lb]=cnt;
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>(s+1);
  	int n=strlen(s+1);
  	memset(dp,-1,sizeof(dp));
  	for(int i=1;i<=n;i++)di[n-i+1]=s[i]-'0';
	cout<

 

你可能感兴趣的:(2020多校牛客,动态规划----数位DP)