和为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])