http://qiemengdao.iteye.com/blog/1660229
I want you!
Description
Given an array Ai(0<=i<n), its length is n; We want to find an another array Bi , which is 0 or 1,and its length is n too;
Besides, Ai and Bi meets the following conditions:
If neither A[i]*B[i] nor A[j]*B[j] equals to 0, then A[i]*B[i] < A[j]*B[j];(0<=i<j<n)
Now , we want to know the maximum of ∑Bi(0<=i<n) you can get.
Input
The input consists of multiple test cases。For each test case ,the first line contains one integer n (1<n<=300).Next line contains n integers.
Output
For each case, output the maximum of ∑Bi.
Sample Input
Sample Output
#include<cstdio>
using namespace std;
int MAX(int a,int b){return a>b?a:b;}
int main(){
int n,i,j,x,k;
int a[301],dp[301];
while(~scanf("%d",&n)){
int c=0;
for(i=0,j=0;i<n;i++){
scanf("%d",&x);
if(x==0)c++;
else {
dp[j]=1;
a[j++]=x;
}
}
int ma=0;
for(i=1;i<j;i++){
for(k=0;k<i;k++){
if(a[i]>a[k]){
dp[i]=MAX(dp[i],dp[k]+1);
}
}
ma=MAX(dp[i],ma);
}
printf("%d\n",ma+c);
}
return 0;
}
ZOJ2136最長上升子序列
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 1001
int main()
{
int t;
while(~scanf("%d",&t))
{
int i,j,n,a[MAXN],b[MAXN],ma;
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++)scanf("%d",&a[i]);
// memset(b,1,sizeof(b));
for(i=0;i<n;i++)b[i]=1;
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
if(a[i]>a[j]&&b[j]+1>b[i])
b[i]=b[j]+1;
}
}
ma=0;
for(i=0;i<n;i++)
{
if(b[i]>ma)ma=b[i];
}
printf("%d\n",ma);
if(t)printf("\n");
}
}
return 0;
}
ZOJ1986 最長公共子序列的nlogn 用二分法講複雜度從n^n降到nlogn
0(t = 1, 2, ..., len(A))。則有動態規劃方程:F[t] = max{1, F[j] + 1} (j = 1, 2, ..., t - 1, 且A
[j] < A[t])。
根據F[]的值進行分類。對於F[]的每一個取值k,我們只需要保留滿
足F[t] = k的所有A[t]中的最小值。設D[k]記錄這個值,即D[k] = min{A[t]} (F[t] = k)。
注意到D[]的兩個特點:
(1) D[k]的值是在整個計算過程中是單調不上升的。
(2) D[]的值是有序的,即D[1] < D[2] < D[3] < ... < D[n]。
需要證明一下
假設d[2] >= d[3]:
a. d[2] 在 d[3] 前面,發現d[3]前的一個元素可以代替d[2]
b. d[2] 在 d[3] 後面,發現d[2]不成立.
於是,主要的工作就是維護這個單調的隊列。
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 40001
int f[MAXN],a[MAXN];
int n;
int see(int len,int value)//尋找第一個大於或等於value的下標
{
int i,j,mid;
i=1;
j=len;
while(i<=j)
{
mid=(i+j)/2;
if(f[mid]>value)j=mid-1;
else if(f[mid]<value)i=mid+1;
else return mid;
}
return i;
}
int main()
{
int t,i,j,k;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
f[1]=a[1];
j=1;
for(i=2;i<=n;i++)
{
if(a[i]>f[j]){
f[++j]=a[i];
// printf(" 1 %d %d\n",j,f[j]);
}
else {
k=see(j,a[i]);
f[k]=a[i];
// printf(" 2 %d %d\n",k,f[k]);
}
}
printf("%d\n",j);
}
return 0;
}