更小的数 dp dfs python

问题描述

小蓝有一个长度均为 nnn 且仅由数字字符 0∼90 \sim 909 组成的字符串,下标从 000n−1n-1n1,你可以将其视作是一个具有 nnn 位的十进制数字 num\text{num}num,小蓝可以从 num\text{num}num 中选出一段连续的子串并将子串进行反转,最多反转一次。小蓝想要将选出的子串进行反转后再放入原位置处得到的新的数字 numnewnum_{new}numnew 满足条件 numnew<num\text{num}_{\text{new}}<\text{num}numnew<num,请你帮他计算下一共有多少种不同的子串选择方案,只要两个子串在 num\text{num}num 中的位置不完全相同我们就视作是不同的方案。

注意,我们允许前导零的存在,即数字的最高位可以是 000,这是合法的。

输入格式

输入一行包含一个长度为 nnn 的字符串表示 num\text{num}num(仅包含数字字符 0∼90 \sim 909),从左至右下标依次为 0∼n−10 \sim n-10n1

输出格式

输出一行包含一个整数表示答案。

样例输入

210102

样例输出

8

样例说明

一共有 888 种不同的方案:

  1. 所选择的子串下标为 0∼10 \sim 101,反转后的 numnew=120102<210102\text{num}_{\text{new}}=120102<210102numnew=120102<210102
  2. 所选择的子串下标为 0∼20 \sim 202,反转后的 numnew=012102<210102\text{num}_{\text{new}}=012102<210102numnew=012102<210102
  3. 所选择的子串下标为 0∼30 \sim 303,反转后的 numnew=101202<210102\text{num}_{\text{new}}=101202<210102numnew=101202<210102
  4. 所选择的子串下标为 0∼40 \sim 404,反转后的 numnew=010122<210102\text{num}_{\text{new}}=010122<210102numnew=010122<210102
  5. 所选择的子串下标为 0∼50 \sim 505,反转后的 numnew=201012<210102\text{num}_{\text{new}}=201012<210102numnew=201012<210102
  6. 所选择的子串下标为 1∼21 \sim 212,反转后的 numnew=201102<210102\text{num}_{\text{new}}=201102<210102numnew=201102<210102
  7. 所选择的子串下标为 1∼41 \sim 414,反转后的 numnew=201012<210102\text{num}_{\text{new}}=201012<210102numnew=201012<210102
  8. 所选择的子串下标为 3∼43 \sim 434,反转后的 numnew=210012<210102\text{num}_{\text{new}}=210012<210102numnew=210012<210102

评测用例规模与约定

对于 202020% 的评测用例,1≤n≤1001 \leq n \leq 1001n100

对于 404040% 的评测用例,1≤n≤10001 \leq n \leq 10001n1000

对于所有评测用例,1≤n≤50001 \leq n \leq 50001n5000

import os
import sys

# 请在此输入您的代码

def dfs(n,a,b):
  m = str(n)
  n = len(m)
  if int(m[a]) > int(m[b]):
    return 1
  elif int(m[a]) == int(m[b]) and a+1 != b and a+1 != b-1:
    return dfs(m,a+1,b-1)
  else:
    return 0



n = str(input())
ans = 0
for i in range(len(n)-1):
  for j in range(i+1,len(n)):
    ans += dfs(n,i,j)

print(ans)
import os
import sys
s=input()
dp=[[0]*5003 for _ in range(5003)]
ans=0
for i in range(1, len(s)):
  for j in range(len(s) - i):
    k= j + i
    if s[j]>s[k]:dp[j][k]=1
    if s[j]==s[k]:dp[j][k]=dp[j + 1][k - 1]
    if dp[j][k]==1:ans+=1
print(ans)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值