1622: 排序工作量之新任务
提交: 33 解决: 17
[提交][状态][讨论版]
题目描述
输入
输出
样例输入
4 3
样例输出
6
1 4 3 2
提示
来源
解析:
第一小问动归解决;
第二小问只交换相邻两数达到使逆序对只加一的目的。
时间复杂度O(tn)
#include<cstdio>
#include<cstring>
int i,j,k,n,t,p;
longlong f[21][211];
int ans[21];
short rec[21];
intswap(int &a, int &b)
{
int t=ans[a];
ans[a]=ans[b];
ans[b]=t;
}
intmain()
{
memset(f,0,sizeof(f));
scanf("%d%d",&n,&t);
if (n==1)
{
printf("1 1");
return0;
}
f[2][1]=1; f[2][0]=1;
for (i=3; i<=n; i++)
for (j=0; j<=i*(i-1)/2; j++)
for (k=0; k<i; k++)
if (j>=k)
f[i][j]+=f[i-1][j-k];
printf("%lld ",f[n][t]);
for (i=1; i<=n; i++)
ans[i]=i;
for (i=1; i<=t; i++)
{
memset(rec,0,sizeof(rec));
p=n;
rec[ans[p]]=p;
while (rec[ans[p-1]+1] == 0) {p--; rec[ans[p]]=p;}
int a=p-1,b=rec[ans[p-1]+1];
swap(a,b);
}
for (i=1; i<=n; i++)
printf("%d ",ans[i]);
return0;
}
第一小问动归解决;
第二小问只交换相邻两数达到使逆序对只加一的目的。
时间复杂度O(tn)
#include<cstdio>
#include<cstring>
int i,j,k,n,t,p;
longlong f[21][211];
int ans[21];
short rec[21];
intswap(int &a, int &b)
{
int t=ans[a];
ans[a]=ans[b];
ans[b]=t;
}
intmain()
{
memset(f,0,sizeof(f));
scanf("%d%d",&n,&t);
if (n==1)
{
printf("1 1");
return0;
}
f[2][1]=1; f[2][0]=1;
for (i=3; i<=n; i++)
for (j=0; j<=i*(i-1)/2; j++)
for (k=0; k<i; k++)
if (j>=k)
f[i][j]+=f[i-1][j-k];
printf("%lld ",f[n][t]);
for (i=1; i<=n; i++)
ans[i]=i;
for (i=1; i<=t; i++)
{
memset(rec,0,sizeof(rec));
p=n;
rec[ans[p]]=p;
while (rec[ans[p-1]+1] == 0) {p--; rec[ans[p]]=p;}
int a=p-1,b=rec[ans[p-1]+1];
swap(a,b);
}
for (i=1; i<=n; i++)
printf("%d ",ans[i]);
return0;
}