hdu 6148 Valley Numer

版权声明:欢迎转载欢迎评论! https://blog.csdn.net/rabbit_ZAR/article/details/82890065

题目:Valley Numer

思路:
数位dp。
dp[len][pre][stt]代表做到第len位,上一位的数是pre,状态为stt的数的个数。
其中bool stt为true即是上升,为false是下降。
其中,当上一位的stt为true时,当前位的数字和上一位相等,当前位的stt也为true;而上一位的stt为false时,当前位的数字和上一位相等,当前位的stt为false。

代码:

#include<bits/stdc++.h>
using namespace std;

#define maxn 100
#define md 1000000007

int a[maxn+5],n=0;
int dp[maxn+5][15][2];

void readin() {
	n=0;
	char x;
	while((~scanf("%c",&x))&&x>='0'&&x<='9') a[++n]=x-'0';
}

int dfs(int len,int pre,int stt,int limit) {
	if(len==n+1) return pre!=10;
	if((!limit)&&(~dp[len][pre][stt])) return dp[len][pre][stt];
	int ans=0;
	int up=9,down=0;
	if(limit) up=a[len];
	if(stt) down=pre;
	for(int i=down;i<=up;i++) {
		ans+=dfs(len+1,((i==0)?(pre==10?10:0):i),i>pre||(i==pre&&stt),(i==a[len]&&limit));
		while(ans>md) ans-=md;
	}
	if(!limit) dp[len][pre][stt]=ans;
	return ans;
}

int slv() {
	memset(dp,-1,sizeof(dp));
	return dfs(1,10,0,1);
}

int main() {
	int T;
	scanf("%d",&T);
	getchar();
	while(T--) {
		readin();
		printf("%d\n",slv());
	}
	return 0;
}

DP百篇达成祭 ∩_∩

猜你喜欢

转载自blog.csdn.net/rabbit_ZAR/article/details/82890065