标签:
题意:有标号l-r的票,要给路人发,当给的票的编号的各数位的总和(可能一个人多张票)不小k时,才开始发给下一个人,求能发多少人。
分析:这个题挺难想的,参考了一下题解,dp[i][sum][left] 长度i 当前数位和sum 前一子树剩余的和
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; ll l,r; int k,lbit[20],rbit[20],used[20][210][1010]; struct node{ ll num,left;//num能发的人数、left前一子树剩余和 node(ll num = 0, ll left = 0) : num(num), left(left) {} node operator += (node b) { num += b.num; left = b.left; return *this; } }dp[20][210][1010]; node dfs(int i,int sum,int left,int le,int re){ if(i==0){ if(sum+left>=k) return node(1,0); return node(0,sum+left); } if(used[i][sum][left]&&!le&&!re) return dp[i][sum][left]; int ll=le?lbit[i]:0; int rr=re?rbit[i]:9; node a(0,left); for(int v=ll;v<=rr;++v){ a+=dfs(i-1,sum+v,a.left,le&&(v==ll),re&&(v==rr)); } if(!le&&!re){ dp[i][sum][left]=a; used[i][sum][left]=1; } return a; } void solve(){ memset(used,0,sizeof(used)); memset(dp,0,sizeof(dp)); int len=0; while(r){ rbit[++len]=r%10; r/=10; lbit[len]=l%10; l/=10; } node t=dfs(len,0,0,1,1); printf("%I64d\n",t.num); } int main() { scanf("%I64d%I64d%d",&l,&r,&k); solve(); return 0; }
标签:
原文地址:http://www.cnblogs.com/zsf123/p/4680932.html