POJ3590 The shuffle Problem题解(置换群+DP)

本文深入解析了POJ3590题目,通过动态规划求解构造长度为n的排列,使置换群自乘得到单位置换的次数最多,并找到字典序最小的置换。讨论了DP状态设计及转移方程,最终给出O(n^2logn)复杂度的解决方案。

题目:POJ3590.
题目大意:要求构造一个长度为 n n n的排列的置换,使得这个置换群能够经过最多次的自乘得到单位置换,输出最多的次数和此时字典序最小的置换.
1 ≤ n ≤ 100 1\leq n\leq 100 1n100.

根据置换的结论,一个置换自乘到单位置换的次数为它拆成的每个轮换长度的lcm,现在问题变成了用若干个和为 n n n的正整数使得它们的lcm最大.

考虑一个DP,设 f [ i ] f[i] f[i]表示若干个数和为 i i i时最大的lcm,发现这个状态不具有最优子结构性质,怎么办?

考虑对于一个数 n n n,构造出来最大的lcm时 n n n必然被分为几个素数幂之和在加上几个 1 1 1的形式.此时我们就可以设 f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i个素数的幂去分解 j j j时最大的lcm,可以列出方程:
f [ i ] [ j ] = max ⁡ { f [ i − 1 ] [ j ] , f [ i ] [ j − 1 ] , max ⁡ p i k ≤ j { f [ i − 1 ] [ j − p i k ] ∗ p i k } } f[i][j]=\max \{ f[i-1][j],f[i][j-1],\max_{p_i^{k}\leq j} \{ f[i-1][j-p_i^{k}]*p_i^{k} \} \} f[i][j]=max{f[i1][j],f[i][j1],pikjmax{f[i1][jpik]pik}}

然后我们就得到了最大的lcm,也就是自乘的最大次数了.

现在的问题就是如何构造一组字典序最小的置换了.首先我们把最大的lcm分解成几个素数幂之积的形式,记它们的和为 s u m sum sum.

显然最小字典序的解肯定是前面的越小越好,最好就是长度为 1 1 1的置换,所以我们先填入 n − s u m n-sum nsum个长度为 1 1 1的轮换.

然后就是把几个素数幂从小到大排个序,依次构造长度为这些素数幂大小的轮换即可.

时间复杂度瓶颈在于DP,由于每次转移时随着 k k k的增长 p i k p_i^{k} pik呈指数级增长,所以时间复杂度为 O ( n 2 log ⁡ n ) O(n^2\log n) O(n2logn).

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

#define Abigail inline void
typedef long long LL;

const int N=100;

int b[N+9],pr[N+9],cp;

void Sieve(int n){
  for (int i=2;i<=n;++i) b[i]=1;
  for (int i=2;i<=n;++i){
  	if (b[i]) pr[++cp]=i;
  	for (int j=1;j<=cp&&i*pr[j]<=n;++j){
  	  b[i*pr[j]]=0;
  	  if (i%pr[j]==0) break;
  	}
  }
}

LL dp[N+9][N+9];

void Get_dp(){
  for (int i=0;i<=N;++i) dp[0][i]=1;
  for (int i=1;i<=cp;++i){
  	dp[i][0]=1;
    for (int j=1;j<=N;++j){
      dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
	  for (int k=pr[i];k<=j;k*=pr[i])
	    dp[i][j]=max(dp[i][j],dp[i-1][j-k]*k);
    }
  }
}

int n,d[N+9],cd;

void Get_d(LL n){
  cd=0;
  LL now=n;
  for (int i=1;i<=cp;++i)
    if (now%pr[i]==0)
      for (d[++cd]=1;now%pr[i]==0;now/=pr[i]) d[cd]*=pr[i];
}

LL ans=0;

Abigail start(){
  Sieve(N);
  Get_dp();
}

Abigail into(){
  scanf("%d",&n);
}

Abigail work(){
  ans=0;
  for (int i=1;i<=n;++i) ans=max(ans,dp[i][n]);
  Get_d(ans);
  sort(d+1,d+cd+1);
}

Abigail outo(){
  printf("%lld",ans);
  int sum=0;
  for (int i=1;i<=cd;++i) sum+=d[i];
  for (int i=1;i<=n-sum;++i)
    printf(" %d",i);
  int now=n-sum;
  for (int i=1;i<=cd;++i){
  	for (int j=1;j<d[i];++j)
  	  printf(" %d",now+j+1);
  	printf(" %d",now+1);
  	now+=d[i];
  }
  puts("");
}

int main(){
  int T;
  scanf("%d",&T);
  start();
  while (T--){
    into();
    work();
    outo();
  }
  return 0;
}
内容概要:本文提出了一种考虑用户行为的基于扩散模型的电动汽车充电场景生成方法,并提供了完整的Python代码实现。该方法充分利用扩散模型在复杂数据分布建模方面的优势,精准捕捉并还原电动汽车用户的实际充电行为特征,如充电时间、持续时长、充电功率及空间分布等,从而生成高保真、多样化的充电负荷场景。文中系统阐述了模型架构设计、训练流程、关键超参数设置及采样策略,实现了对充电需求不确定性的精细化建模,为后续电网规划、负荷预测、电力市场仿真及有序充电策略研究提供了高质量的数据基础。; 适合人群:具备一定Python编程能力和机器学习基础知识,从事电力系统、交通电气化、综合能源系统、智能电网等领域研究的科研人员、工程师及研究生,尤其适用于关注负荷建模、不确定性分析与数据驱动仿真方法的研究者。; 使用场景及目标:①生成具有真实用户行为特征的电动汽车充电负荷场景,支撑高比例电动汽车接入下的电力系统影响分析;②服务于车网互动(V2G)、需求响应、配电网扩容规划等应用场景,提升模型对用户随机行为的刻画能力;③作为深度生成模型在能源领域应用的典型案例,帮助研究人员掌握扩散模型的原理与工程实现技巧。; 阅读建议:建议读者结合所提供的Python代码逐模块深入学习,重点关注数据预处理流程、扩散过程的正向加噪与反向去噪网络设计,以及条件输入如何融合用户行为特征,并鼓励在自有数据集上进行迁移训练与参数调优,以充分理解模型对复杂充电行为模式的学习与生成机制。
内容概要:本文围绕基于DDPM(去噪扩散概率模型)的电动汽车充电行为场景生成展开研究,提出了一种融合用户行为特征的充电行为建模方法。通过Python实现了扩散模型的核心算法,旨在对电动汽车用户的充电时间、持续时长、充电功率等关键行为变量的不确定性进行高保真度模拟与多样化场景生成。该方法充分体现了数据驱动特性,利用真实充电数据训练模型,有效捕捉实际充电行为的随机性、个体差异与时序依赖性,生成具有统计一致性的多维行为场景样本,为电力系统规划、微电网优化调度、有序充电管理及V2G策略设计等应用提供可靠的概率性输入。研究重点涵盖了前向加噪与反向去噪过程的理论实现、网络架构设计、数据预处理流程及采样策略。; 适合人群:具备一定Python编程基础和机器学习理论背景的研究生、科研人员,以及从事智慧交通、新型电力系统、新能源汽车能源管理、城市基础设施规划等领域的技术研发工程师。; 使用场景及目标:①支撑电动汽车集群充电负荷的概率性预测与多场景分析;②服务于高比例电动汽车接入背景下的微电网、主动配电网优化调度研究;③为充电基础设施规划、车网互动(V2G)控制策略与需求响应机制设计提供精细化的行为建模工具;④作为扩散模型在能源与交通交叉领域应用的典型案例,用于教学演示与学术研究,深化对生成模型解决现实世界不确定性问题能力的理解。; 阅读建议:建议读者结合所提供的Python代码进行实践操作,深入理解DDPM的数学原理与实现细节,重点关注数据标准化、噪声调度、U-Net网络结构设计及反向采样过程。推荐同步学习扩散模型的基础理论文献,以更好地把握模型超参数选择与训练技巧,并尝试将其迁移应用于其他类型的能源消费行为或交通出行场景的生成任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值