开始想了一下动态规范和贪心什么的,完全没思路。
最后用dfs+回溯竟然没超时。
import java.util.*;
public class Main{
private static int result=0;
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int k=sc.nextInt();
int[] nums=new int[n];
for(int i=0;i<n;i++){
nums[i]=sc.nextInt();
}
ArrayList<Integer> index=new ArrayList<>(); //数组中0的位置信息
ArrayList<Integer> loss=new ArrayList<>();// 缺失的数字集合
HashSet<Integer> set=new HashSet<>(); // 用set的contain方法快一点
for(int i=0;i<n;i++){
set.add(nums[i]);
if(nums[i]==0) {
index.add(i);
continue;
}
//减掉数组本身的正序数
for(int j=i+1;j<n;j++){
if(nums[j]>nums[i]&nums[i]!=0) k--;
}
}
for(int i=1;i<=n;i++){
if(!set.contains(i)){
loss.add(i);
}
}
backTracking(nums,index,loss,k,0);
System.out.println(result);
}
sc.close();
}
//回溯的模板
public static void backTracking(int[] nums,ArrayList<Integer> index,ArrayList<Integer> loss,int k,int d){
if(k==0&&loss.size()==0){
result++;
return;
}
if(k<0||d>=index.size()) return;
int cur=index.get(d);
for(int i=0;i<loss.size();i++){
int tmp=loss.remove(i);
nums[cur]=tmp;
backTracking(nums,index,loss,k-count(nums,cur),d+1);
nums[cur]=0;
loss.add(i,tmp);
}
}
//插入一个数之后新增的正序数
public static int count(int[] nums,int pos){
int ans=0;
for(int i=0;i<pos;i++){
if(nums[i]>0&&nums[i]<nums[pos]) ans++;
}
for(int i=pos+1;i<nums.length;i++){
if(nums[i]>0&&nums[i]>nums[pos]) ans++;
}
return ans;
}
}


京公网安备 11010502036488号