和为k的不连续子序列个数

有一个字符串,明明想取该字符串的子序列(子序列可以不连续),使得改子序列是9的倍数,子序列可以包括前导0,一共可以取多少个合法子序列,输出的字符串长度不超过200000,仅由‘0’-‘9’组成

 

第一种: 和为9的倍数

9这个数字很特殊,为什么呢?

18 = 9+1+8  = 1+8 也是9的倍数,所以问题就转为为:找一串数字和为9的倍数的可不连续子序列

 

输入:

1 1 8 8 

输出

5

 

输入:

9 1 1 0 6 4 8 7 2 3 1 0 1

输出

879

 

 1 arr = list(map(int, input()))
 2 k = 9
 3 res =[]
 4 
 5 def find(i, pre):
 6     if i >= len(arr) :  return 
 7     pre += arr[i]
 8     if pre%k==0: 
 9         res.append(pre)
10     find(i+1, pre)
11     pre -= arr[i]
12     find(i+1, pre)
13 
14 pre = 0
15 vis = [0]*len(arr)
16 find(0, pre)
17 print(len(res))

 

还有一种写法就是

from copy import deepcopy
arr = list(map(int, input()))
k = 9
res =[]
ans = [0]*9

def find2():
    for num in arr:
        tmp = deepcopy(ans) #记录前一次状态
        ans[num%9] += 1 #每新加一个的数,更新下余数数组ans
        for i in range(9): #对于[0-8]
            ans[(num+i)%9] += tmp[i] #更新num加进来,each values of `ans` changes

find2()
print(ans[0])

 

 

和为K的子序列个数

给一个数组 a,长度为 n,若某个子序列中的和为 K 的倍数,那么这个序列被称为“K 序列”。现在要你 对数组 a 求出最长的子序列的长度,满足这个序列是 K 序列。 
第一行为两个整数 n, K, 以空格分隔,第二行为 n 个整数,表示 a[1] ∼ a[n],输出一个整数表示最长子序列的长度 m
输入:
7 5
10 3 4 2 2 9 8

 

输出:
6

 

题解

按照上一题的思路,dp[s]保存的是余数为s的最长子序列长度

 1 from copy import deepcopy
 2 
 3 n, k = map(int, input().split())
 4 arr = list(map(int, input().split()))
 5 
 6 dp = [0]*(k+1)
 7 for i in range(n):
 8     tmp = deepcopy(dp)
 9     for j in range(k):
10         x = tmp[j] +1 if tmp[j] else 0
11         dp[(arr[i]+j)%k] = max(x, tmp[(arr[i]+j)%k]) 
12     if dp[arr[i]%k] == 0:
13         dp[arr[i]%k] = 1
14 print(dp[0])

 

 

这是一个博主的写法如下所示:http://t.zoukankan.com/jiamian-p-12764957.html

from copy import deepcopy

n, k = map(int, input().split())
arr = list(map(int, input().split()))

dp = [0]*(k+1)
for i in range(n):
    tmp = deepcopy(dp)
    for j in range(k):
        if j==0 or tmp[j]!=0:
            dp[(j+arr[i])%k] = tmp[j]+1
    for j in range(k):
        tmp[j] = max(tmp[j], dp[j])
print(dp[0])

 

 

posted @ 2022-04-17 20:37  浅忆~  阅读(501)  评论(0编辑  收藏  举报