zoukankan      html  css  js  c++  java
  • 洛谷P3413 萌数

    https://www.luogu.com.cn/problem/P3413

    回文长度2或者3就可以裁定,值得注意的是dp[pos][pre][ppre]可能应对3334321和5554321(都有321),所以要引入最新的变量才行。

    dp[pos][pre][ppre][sum],具体套了板子,返回的时候记得让pre和ppre的数字不是前导0

    #include<iostream>
    #include<queue>
    #include<string>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int T, n, m, len, a[2020];
    ll l, r, dp[1010][14][13][3];
    ll mod = 1e9 + 7;
    
    //                                  记录答案 ppre是1能算
    ll dfs(int pos, int pre, int ppre, ll sum, int d, int lead, int limit)
    //pos搜到的位置
    //pre前一位数
    //st当前公差最大差值
    //sum整个数字的最大价值
    //d共差
    //lead判断是否有前导0
    //limit判断是否有最高位限制
    {
    	if (pos > len) return sum;//dp结束
    	//记录状态(计划搜索)
    	//注意d有负数,最小可以到-9,所以记录时数组下标是d+10
    	if ((dp[pos][pre][ppre][sum] != -1 && (!limit) && (!lead)) && d == 1) return dp[pos][pre][ppre][sum] %= mod;
    	ll ret = 0;
    	int res = limit ? a[len - pos + 1] : 9;//最高位最大值
    
    	for (int i = 0; i <= res; i++)
    	{
    		//有前导0且这位也是前导0,一切不变只有位数变化
    		if ((!i) && lead) {
    			ret += dfs(pos + 1, 0, 0, 0, 0, 1, limit && (i == res));
    			ret %= mod;
    		}
    
    		//有前导0但这位不是前导0(这位是数字的最高位)开始有前一位,一个数形成等差数列
    		else if (i&&lead) {//当前位置是最高位
    			ret += dfs(pos + 1, i, 0, 0, 0, 0, limit && (i == res));
    			ret %= mod;
    		}
    		else {//前面已经有非0的数字了lead = 0
    			ll su = (i == pre)  || (sum == 1);
    			if (d == 1 && i == ppre) su = 1;
    			ret += dfs(pos + 1, i, pre, su, 1, 0, limit && (i == res));
    			ret %= mod;
    
    		}
    	}
    	ret %= mod;
    	//没有前导0和最高限制时可以直接记录当前dp值以便下次搜到同样的情况可以直接使用。
    	return (!limit && !lead && d == 1) ? dp[pos][pre][ppre][sum] = ret : ret;
    }
    int list[2020];
    
    
    ll cal(string  x,int cl)
    {
    	len = 0;
    	
    	for (int i = 0; i < x.length(); i++) {
    		list[i] = x[i] - '0';
    	}
    	list[x.length()-1] -= cl;
    
    	for (int i = x.length() - 1; i >= 0; i--) {
    		if (list[i] < 0) {
    			list[i] = 9;
    			list[i - 1] --;
    		}
    	}
    	int f = 0;
    	for (int i = 0; i < x.length(); i++) {
    		if (f == 0 && list[i] == 0) list[i] = -1;
    		if (list[i] > 0) f = 1;
    	}
    	
    	for (int i = x.length() - 1; i >= 0; i--) {
    		if (list[i] == -1) break;
    		a[++len] = list[i];
    	}
    	memset(dp, -1, sizeof dp);
    	return dfs(1, 0, 0, 0, 0, 1, 1);//-38是随便赋的其实赋成-10就行了……
    }
    
    string sn;
    
    int main()
    {
    	
    	cin >> sn;
    	ll ans = cal(sn, 1);
    	cin >> sn;
    	ll cns = cal(sn, 0); 
    	cout << (cns - ans + mod) % mod << endl;
    	//l是0的时候要特别注意!
    	//printf("%lld
    ", part(r) - part(l-1));
    	
    	return 0;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    结对编程2
    结对编程总结:简单的四则运算生成程序
    我的结对项目心得与代码规范
    一个团队和他们的调查表-----("调查表与调查结果分析"心得体会)
    目标?我定好了!(我的软件工程课目标)
    Jmeter响应数据为乱码的处理
    软件工程课程建议
    结对编程之Fault、Error、Failure
    我的结对项目编程感想
    调查问卷后的心得
  • 原文地址:https://www.cnblogs.com/lesning/p/13646038.html
Copyright © 2011-2022 走看看