首页 > 其他分享 >P4163 [SCOI2007]排列

P4163 [SCOI2007]排列

时间:2023-05-12 09:57:07浏览次数:56  
标签:排列 vert int le right P4163 kmax include SCOI2007

Problem

给一个数字串 \(s\) 和正整数 \(d\), 统计 \(s\) 有多少种不同的排列能被 \(d\) 整除(可以有前导 \(0\))。
多组数据。

\(\left\vert s\right\vert \le 10,1 \le d \le 1000,1 \le t \le 15\)

Input

第一行一个整数 \(t\),表示数据组数。
接下来 \(t\) 行,每行一个数字串 \(s\) 和一个整数 \(d\)。

Output

每组数据一行一个整数表示答案。

Sample

Input 1

7
000 1
001 1
1234567890 1
123434 2
1234 7
12345 17
12345678 29

Output 1

1
3
3628800
90
3
6
1398

Solution

观察到 \(\left \vert s \right \vert\) 很小,可以尝试状压。

定义 \(f_{i,j}\) 表示当前选数集合为 \(i\),形成的数模 \(d\) 与 \(j\) 的方案数。转移方程不难写出:

\(f[i | 1 << k][ (j\times 10 + a_k) \% d ] = f[i | 1 << k][ (j\times 10 + a_k) \% d ] + f[i][j]\)

但直接转移会计算重复,因为 \(s\) 中会有相同的元素。

又因为 \(\left \vert s \right \vert \le 10\),故每次转移时标记下即可。

代码:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int kmax = 1e3 + 3;
const int kmaxM = 13;

int a[kmax];
bool b[kmax];
char c[kmax];
int t, n, d;
long long f[1 << kmaxM][kmax];

void Solve() {
  scanf("%s %d", c, &d);
  n = strlen(c);
  for (int i = 0; i < n; i++) {
    a[i] = c[i] - '0'; 
  }
  memset(f, 0, sizeof(f));
  f[0][0] = 1;
  for (int i = 0; i < 1 << n; i++) {
    memset(b, 0, sizeof(b)); // 清空标记
    for (int j = 0; j < n; j++) {
      if (i & (1 << j)) continue;
      if (b[a[j]]) continue; // 标记过,不要重复计算
      b[a[j]] = 1; // 添加标记
      for (int k = 0; k < d; k++) {
        f[i | (1 << j)][(k * 10 + a[j]) % d] += f[i][k]; // 转移
      }
    }
  }
  printf("%lld\n", f[(1 << n) - 1][0]);
}

int main() {
  scanf("%d", &t);
  while (t--) { // 多组数据
    Solve();
  }
  return 0;
}

标签:排列,vert,int,le,right,P4163,kmax,include,SCOI2007
From: https://www.cnblogs.com/ereoth/p/17392902.html

相关文章

  • shell排列3个整数
    用户输入3个整数,脚本根据数字大小依次升序输出3个数字#!/bin/bashecho"Pleaseenterthreeintegers:"read-rnum1num2num3echo"Sortedintegersinascendingorder:"echo"$num1$num2$num3"|tr'''\n'|sort-n|tr'\......
  • CodeForces - 626B Cards (全排列&模拟)
    TimeLimit: 2000MS MemoryLimit: 262144KB 64bitIOFormat: %I64d&%I64uCodeForces-626BCardsSubmit StatusDescriptionCatherinehasadeckof ntakeanytwo(notnecessarilyadjacent)cardswithdifferentcolorsandexchangethemforanewcardof......
  • 排列组合的应用
    目录应用应用1:Leetcode.39题目分析代码实现方法一方法二应用2:Leetcode.40题目分析代码实现应用3:Leetcode.216题目分析代码实现方法一方法二应用4:Leetcode.78题目分析代码实现应用5:Leetcode.90题目分析代码实现应用6:Leetcode.77题目分析代码实现应用7:Leetcode.46题目分析代码实现应......
  • 【算法基础】DFS深度优先算法 —— AcWing 843. n-皇后问题 AcWing 842. 排列数字
    n-皇后问题是一个经典的dfs深度优先遍历的题目,在题解这一题之前,将由浅入深,先讲解一个n-皇后问题的母题。-------AcWing842.排列数字 [AcWing842].排列数字题目概述给定一个整数 n,将数字 1∼n排成一排,将会有很多种排列方法。现在,请你按照字典序将所有的排列方法输出。输入格......
  • 6 排列与组合:排序、排位、排
    计算排位数目如要算出n个独立对象的排名方式的确切数目,可按下式进行计算:n!=n×(n-1)x(n-2)x…×3×2×1圆形排位如果有个对象需要进行圆形排位,则可能的排位数目按下式进行计算:(n-1)!按类型排位练习:排列排列是指从一个较大(n个)对象群体中取出一定数目(r个)对象进行排......
  • 番外篇:分享一道用Python基础+蒙特卡洛算法实现排列组合的题目(附源码)
    今日鸡汤夕阳无限好,只是近黄昏。    大家好,我是Python进阶者。    是不是觉得很诧异?明明上周刚发布了这篇:分享一道用Python基础+蒙特卡洛算法实现排列组合的题目(附源码),今天又来一篇,名曰番外篇!其实今天是想给大家分享【......
  • 分享一道用Python基础+蒙特卡洛算法实现排列组合的题目(附源码)
    今日鸡汤沙场烽火连胡月,海畔云山拥蓟城。    大家好,我是Python进阶者。这篇文章的题目真的是很难取,索性先取这个了,装个13好了。前言    前几天在才哥交流群里,有个叫【RickXiang】的粉丝在Python交流群里问了一道关于排列组合的问题,初步一看觉得很简单,实际上确实是有难度的......
  • LeetCode 周赛 343(2023/04/30)结合「下一个排列」的贪心构造问题
    本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]提问。大家好,我是小彭。今天是五一假期的第二天,打周赛的人数比前一天的双周赛多了,难道大家都只玩一天吗?这场周赛是LeetCode第343场单周赛,如果不考虑第一题摆烂的翻译,整体题目质量还是很不错哒。往期回顾:L......
  • 先序排列
    #[NOIP2001普及组]求先序排列##题目描述给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,且二叉树的节点个数$\le8$)。##输入格式共两行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。##输出格式共一行一个字符串,表......
  • 【完全背包的排列问题】NO377. 组合总和 Ⅳ
    [完全背包排列问题]377.组合总和Ⅳ给你一个由不同整数组成的数组nums,和一个目标整数target。请你从nums中找出并返回总和为target的元素组合的个数。题目数据保证答案符合32位整数范围。示例1:输入:nums=[1,2,3],target=4输出:7解释:所有可能的组合为:(1,......