您的位置:首页 > 其它

USACO 4.3 PROB Buy Low, Buy Lower

2014-04-17 23:22 316 查看
题目意思:

给n个数,要求最长的递减子序列的长度,并求出不相同的个数(n<=5000)

例如,对于序列17,8,3,3,最长递减子序列为3,不同的个数为2(两个17,8,3是重复的!)

思路:

求最长递减子序列的长度很简单,有O(n*n)的做法,也有O(n*log(n))的做法

O(n*n)的做法是 d(i) = max{0,d(j) | j<i,A(j)<A(i) } + 1

d(i) 表示以第i位结尾的最长递减子序列的长度

O(n*log(n))的做法见刘汝佳的书

求不相同的个数也用dp:(注意要不相同)

考虑到要不相同,所以从最后j是最后一个满足 A[j] = A[i] 的位置(如果不存在则为-1)

num(i) = ∑num[k](j<k<i,A[k]>A[i],d[k]+1=d[i])

需要注意的是,这其中有把num(i)赋为1的小细节

最后再从头到尾扫一遍得到答案

最后,可以构造出

4999 5000 4997 4998 ..... 这样的样例,答案是2^2500,远远超出了整数范围,所以需要使用高精度

我觉得这样的样例会超出1s的时限。。。但是没有改成O(n*log(n))的做法....也不知道在统计个数的时候怎么处理

java中有现成的大整数的实现~

这里mark一下使用java中的大整数~

/*
ID: jasison2
TASK: buylow
LANG: JAVA
*/
/**
* @date	2014-04-17 20:25:56
* @author  jasison
* @email   jasison27@gmail.com
* @website http://www.jiangshan27.com */
import java.util.*;
import java.io.*;
import java.math.*;

public class buylow {
public static int n,ans1;
public static int[] d,a;
public static BigInteger ans2;
public static BigInteger[] num;
public static  int N = 5003;
public static void main(String[] args) throws Exception {
d = new int
;
a = new int
;
num = new BigInteger
;
BufferedReader infile = new BufferedReader(new FileReader("buylow.in"));
PrintWriter outfile = new PrintWriter(new BufferedWriter(new FileWriter("buylow.out")));
StringTokenizer st = new StringTokenizer(infile.readLine());
n = Integer.parseInt(st.nextToken());
int index = 0;
while (index < n) {
st = new StringTokenizer(infile.readLine());
while (st.hasMoreTokens()) {
a[index++] = Integer.parseInt(st.nextToken());
}
}
solve();
outfile.println(ans1+" "+ans2);
outfile.close();
}
public static void solve() {
ans1=0;
for(int i=0;i<n;++i){
d[i]=0;
num[i]=BigInteger.ZERO;
int st=i-1;
while(st>=0&&a[st]!=a[i]){
st--;
}
for(int j=st+1;j<i;++j){
if(a[i]<a[j]){
if(d[i]<d[j]){
d[i]=d[j];
num[i]=num[j];
}else if(d[i]==d[j]){
num[i]=num[i].add(num[j]);
}
}
}
if (num[i]==BigInteger.ZERO && st==-1){
num[i]=BigInteger.ONE;
}
d[i]++;
if(ans1<d[i]){
ans1=d[i];
ans2=num[i];
}else if(ans1==d[i]){
ans2=ans2.add(num[i]);
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: