poj 1850 数位dp/排列组合

本文介绍了一种使用数位动态规划(数位DP)的方法来解决字符串编号计算问题,该问题要求根据字典序对字符串进行编号。文章通过一个具体的编程实现案例展示了如何判断字符串的有效性并计算其编号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:
字符串可以由26个小写字母组成,按字典序排列。a,b,……..abcde..xyz编号为1,2,…….。给出一个字符串,求他的编号,如果不符合要求,输出0.
分析;
因为是组合数学分类的题目,读完题就一直考虑怎么用组合?然而我只能想到用搜索去做QAQ。数位dp(其实这题记忆化并没有什么卵用),搜索一下即可。组合的话,实在无能为力啊!之后看了别人用排列组合做的,这里写图片描述
图片来自:http://blog.youkuaiyun.com/lyy289065406/article/details/6648492
如果知道这个数学公式就能做出来了QAQ

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=50;
int f[N][N];
char bit[50];
int len;
int dfs(int pos,int pre,bool lim)
{
    if(pos==len)return pre!=0;
    if(!lim&&pre!=0&&f[pos][pre]!=-1)return f[pos][pre];
    int ans=0;
    int m=lim?bit[pos]-'a'+1:26;
    if(pre==0)ans+=dfs(pos+1,0,0);
    for(int i=pre+1;i<=m;i++){
        ans+=dfs(pos+1,i,lim&&i==m);
    }
    if(!lim&&pre!=0)f[pos][pre]=ans;
    return ans;
}

int main()
{
    //freopen("f.txt","r",stdin);
    memset(f,-1,sizeof(f));
    scanf("%s",bit);
    len=strlen(bit);
    for(int i=1;i<len;i++){
        if(bit[i]<=bit[i-1]){
            puts("0");return 0;
        }
    }
    printf("%d\n",dfs(0,0,1));
    return 0;
}
<think>好的,用户想了解POJ问题24的解法或计算方法。首先,我需要确认POJ 24的具体题目内容。但根据提供的引用资料,没有直接提到POJ 24的信息。引用中提到的题目有3021、3331等,可能用户记错了编号?或者POJ 24可能是一个经典问题,但需要进一步确认。 接下来,我会检查常见的POJ题目列表。例如,POJ 1000是A+B问题,POJ 1001是高精度幂运算,POJ 1011是木棍问题等。但编号24可能不是常见问题。可能需要用户提供更多信息,比如题目名称或描述。不过根据现有引用,引用3提到了高精度算法,可能与阶乘计算有关,如POJ 3331。但用户明确提到的是问题24,所以可能需要假设题目类型。 假设POJ 24是一个类似阶乘计算的高精度问题,或者涉及动态规划,如引用1中的DP解法。例如,问题可能要求计算排列组合或类似数学问题,需要高精度处理。例如,计算卡特兰数或斐波那契数列的大数情况。 在这种情况下,建议用户检查题目编号是否正确,或提供更多题目细节。如果问题24确实存在且需要高精度计算,可以参考引用3中的方法,使用数组处理大数运算。如果是动态规划问题,则参考引用1中的DP思路。如果问题涉及排序或搜索,可能需要快速排序等算法,如示例中的Python代码。 由于信息不足,可能需要进一步询问用户确认题目内容。或者给出一般性的高精度算法或动态规划的解决方法,帮助用户应对可能的题目类型。</think>[用户可见层] 关于POJ问题24的解决方案,由于POJ题目编号系统包含上千道题且引用资料未明确提及编号24的题目[^2],建议先确认题目名称或具体要求。以下是两种常见POJ题目类型的通用解法框架: --- ### 情况一:若为高精度计算问题(如阶乘、大数运算) 参考POJ 3331的解法[^3],典型步骤如下: 1. **数组存储法**:用整型数组存储大数,每个元素代表一位数字 2. **逐位计算**:例如计算$n!$时,从1到n循环相乘,每次处理进位 3. **结果输出**:倒序输出数组中的有效数字 示例代码框架: ```python def factorial(n): result = [1] # 初始值为1 for i in range(2, n+1): carry = 0 for j in range(len(result)): product = result[j] * i + carry result[j] = product % 10 carry = product // 10 while carry > 0: result.append(carry % 10) carry //= 10 return ''.join(map(str, reversed(result))) ``` --- ### 情况二:若为动态规划问题(如背包、路径优化) 参考POJ 3021的DP思路[^1],典型步骤: 1. **定义状态**:如$dp[i][j]$表示前i个物品达到状态j的最小代价 2. **状态转移方程**:根据问题条件建立递推关系 3. **边界条件初始化**:如$dp[0][0] = 0$ 4. **结果提取**:遍历最终状态寻找最优解 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值