当前位置: 首页 > news >正文

POJ3590 The shuffle Problem——置换群+DP/递推预处理

显然,这是一个置换群问题,答案m就是将n这个数拆成k个(1=<k<=n),k个数能够得出的最小公倍数。

简略证明:

序列会被分为若干个群,每个群需要交换这个群的size次才能够回复原位,因此,问题转化成求将n这个数拆成k个(1=<k<=n),k个数能够得出的最小公倍数,以及满足题目要求的字典序最小的序列。

DP预处理:

dp[i][j]表示将i这个数字划分成j个,这j个数能够组成的最小公倍数。那么方程就是dp[i][j]=max{lcm(dp[k][j-1],i-k)}  (j-1<=k<=i-1)

注意,要令字典序最小,必须使划分的集合数尽量多,并按照集合大小从小到大排序,加以匹配即可。

参考代码:

program poj3590;//By_Thispoet
const maxn=100;
var i,j,k,m,n,p,q,test    :longint;
    dp,src                :array[0..maxn,0..maxn]of longint;
    ans                   :array[0..maxn]of longint;
function gcd(i,j:longint):longint;
begin
  if j=0 then exit(i);exit(gcd(j,i mod j));
end;

function lcm(i,j:longint):longint;
var x:longint;
begin
  x:=gcd(i,j);exit(i*j div x);
end;

procedure getans(i,code:longint);
var p,j:longint;
begin
  if code=1 then begin
    inc(ans[0]);ans[ans[0]]:=i;exit;
  end;p:=src[i][code];getans(p,code-1);inc(ans[0]);ans[ans[0]]:=i-p;
end;

procedure swap(var i,j:longint);
begin
  if i<>j then begin i:=i xor j;j:=i xor j;i:=i xor j;end;
end;

procedure qsort(l,r:longint);var i,j,k:longint;
begin
  i:=l;j:=r;k:=ans[(i+j)>>1];repeat
    while ans[i]<k do inc(i);while ans[j]>k do dec(j);
    if i<=j then begin swap(ans[i],ans[j]);inc(i);dec(j); end;
  until i>j;if l<j then qsort(l,j);if i<r then qsort(i,r);
end;

procedure printf(i,code:longint);var j:longint;
begin
  for j:=i+1 to i+ans[code]-1 do write(j,' ');
  if i=n-ans[code]+1 then begin write(i);exit;end;write(i,' ');printf(i+ans[code],code+1);
end;

begin
  readln(test);filldword(dp,sizeof(dp)shr 2,0);
  for i:=1 to 100 do begin dp[i][1]:=i;dp[i][0]:=1;end;
  for i:=1 to 100 do for j:=2 to i do begin
    for k:=i-1 downto j-1 do begin
      p:=lcm(dp[k][j-1],i-k);if p>dp[i][j] then begin
        dp[i][j]:=p;src[i][j]:=k;
      end;
      if dp[i][j]>=dp[i][dp[i][0]] then dp[i][0]:=j;
    end;
  end;
  while test>0 do begin
    readln(n);ans[0]:=0;
    write(dp[n][dp[n][0]],' ');getans(n,dp[n][0]);
    qsort(1,ans[0]);printf(1,1);writeln;
    dec(test);
  end;
end.

 

转载于:https://www.cnblogs.com/Thispoet/archive/2011/10/31/2230592.html

相关文章:

  • 生成excel控制类
  • jdk和tomcat环境变量配置
  • SQL中的行号ROW_NUMBER()
  • 使用 CTTeleyphonyCenter 截获来去电及短信消息
  • 翻译]游戏主循环
  • Ural_1126. Magnetic Storms 单调队列
  • adb shell dumpsys 命令 查看内存
  • hibernate连接Mysql中文乱码处理
  • very_confusing
  • HDOJ4070
  • apche IIS .htaccess httpd.ini Rewrite RewriteRule详解
  • 60个数据窗口技巧(转)
  • Android基础之Android硬件
  • VIM之Project 项目管理工具
  • 复制构造函数与禁止复制即函数值传递的原理
  • [Vue CLI 3] 配置解析之 css.extract
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • css属性的继承、初识值、计算值、当前值、应用值
  • Docker 笔记(2):Dockerfile
  • flutter的key在widget list的作用以及必要性
  • HTTP--网络协议分层,http历史(二)
  • PHP 小技巧
  • PHP面试之三:MySQL数据库
  • PHP那些事儿
  • Python中eval与exec的使用及区别
  • supervisor 永不挂掉的进程 安装以及使用
  • text-decoration与color属性
  • Vue 动态创建 component
  • Vue小说阅读器(仿追书神器)
  • Windows Containers 大冒险: 容器网络
  • 初识 webpack
  • 分布式事物理论与实践
  • 精彩代码 vue.js
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 普通函数和构造函数的区别
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 我看到的前端
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​Spring Boot 分片上传文件
  • #Linux(权限管理)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (八)c52学习之旅-中断实验
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .apk文件,IIS不支持下载解决
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .NET Core WebAPI中封装Swagger配置
  • .NET 分布式技术比较
  • .NET 设计一套高性能的弱事件机制
  • .NET上SQLite的连接