POJ 2085 JAVA

来源:互联网 发布:unity3d培训多少钱蓝鸥 编辑:程序博客网 时间:2024/04/30 11:25

http://poj.org/problem?id=2085



正常方法可以按顺序遍历,对每一个组合求逆序数t。时间复杂度 O(n!*n^2)
卜过我想到了一种比较迅速的迭代方法


以5 9为例 (length=5 , target=9)
考虑数组
12345
以1为开头,最大的是15432,显然t=4*(4-1)/2=6<9
故把1放在末位(这里不放在中间的原因是如果把1放中间,那么不可能达到t的最大化,打个比方,5 10时不可能得到54321)
考虑2 3 4 5,其实只需考虑 4 (9-4)即 4 5,
以此类推,考虑 3 2,得出 3 2 为 2 3 1
这里有关length的边界条件为递推即可,当length为2,1时根据target得到所需的数组。
时间复杂度为O(n)

代码如下,递归的比较好理解一点,不带递归的快一点,然而这两种方法都TLE,求帮助。。。


递归的:

import java.util.Scanner;


public class Inversion {
static int target,result[];
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int l,t;
String str;
while(!"-1 -1".equals(str=sc.nextLine())){
l=Integer.parseInt(str.split(" ")[0]);
t=Integer.parseInt(str.split(" ")[1]);
result=new int[l];
I(0,l-1,l,t);
for(int i=0;i<l;i++)
System.out.print(result[i]);
System.out.println();
}
}
//1 2 3 4 5 6 7
public static void I(int start,int end,int length,int target){
if(length==2){
if(target==0){
result[start]=1;
result[end]=2;
}else{
result[start]=2;
result[end]=1;
}
}else if(length>2){
if(target>((length-1)*(length-2)/2)){
result[end]=1;
I(start,end-1,length-1,target-length+1);
addI(start,end-1);
}else{
result[start]=1;
I(start+1,end,length-1,target);
addI(start+1,end);
}
}else if(length==1){
result[start]=1;
}
}
public static void addI(int start,int end){
for(int i=start;i<=end;i++)
result[i]++;
}
}


不带递归的:

import java.util.Scanner;


public class Inversion2 {
static long target;
static int result[];
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int l,t;
String str;
while(!"-1 -1 ".equals(str=sc.nextLine())){
l=Integer.parseInt(str.split(" ")[0]);
t=Integer.parseInt(str.split(" ")[1]);
result=new int[l];
I(0,l-1,l,t);
System.out.print(result[0]);
for(int i=1;i<l;i++)
System.out.print(" "+result[i]);
System.out.println();
}
}
//1 2 3 4 5 6 7
public static void I(int start,int end,int length,int target){
boolean over=false;
while(!over){
if(length==2){
if(target==0){
result[start]+=1;
result[end]+=2;
}else{
result[start]+=2;
result[end]+=1;
}
over=true;
}else if(length>2){
if(target>((length-1)*(length-2)/2)){
result[end]+=1;
end--;
length--;
target=target-length;
addI(start,end);
}else{
result[start]+=1;
start++;
length--;
addI(start,end);
}
}else if(length==1){
result[start]+=1;
over=true;
}
}
}
public static void addI(int start,int end){
for(int i=start;i<=end;i++)
result[i]++;
}
}

0 0
原创粉丝点击