1. Hdu Max sum :
题意: 最大连续和,但要输出这个序列的起始和末尾;
两种线性时间算法: 1,前缀和 S[j]--S[i-1]: S[i-1]最小
2,Dp 状态转移方程 : S[i]=Max(0, S[i-1])+A[i];
#include<iostream>
#define N 100010
using namespace std;
int a[N],d[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.cpp","r",stdin);
#endif // ONLINE_JUDGE
int test,n,i,Max,k,f,e;
cin>>test;
k=0;
while(test--)
{
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
d[0]=0;
for(int i=1;i<=n;i++)
d[i]=d[i-1]+a[i];
Max=-9999;
int Min=d[0];
for(int i=1;i<=n;i++)
{
if(d[i]-Min>Max) { Max=d[i]-Min; e=i;}
if(d[i]<Min) Min=d[i];
}
f=e;
int t=0;
for(int i=e;i>0;i--)
{
t+=a[i];
if(t==Max) f=i;
}
printf("Case %d:\n",++k);
printf("%d %d %d\n",Max,f,e);
if(test) cout<<endl;
}
return 0;
}
2. poj 2533 Longest Ordered Subsequence
最长上升子序列: 状态转移方程: Dp[i]== max(dp[j] ( i<j.A[i]<A[j] )) +1;
const int maxn=1010;
using namespace std;
int dp[maxn];
int A[maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.cpp","r",stdin);
#endif // ONLINE_JUDGE
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d",&A[i]);
dp[1]=1;
int Max=1;
int m;
for(int i=2;i<=n;i++)
{
m=0;
for(int j=1;j<i;j++)
{
if(A[j]<A[i]&&dp[j]>=m)
m=dp[j];
}
dp[i]=m+1;
if(dp[i]>Max) Max=dp[i];
}
printf("%d\n",Max);
}
return 0;
}
nlogn :
#define MP make_pair
#define PB push_back
#define AA first
#define BB second
#define BG begin()
#define ED end()
#define SZ size()
int a[100005];
int main(){
#ifndef ONLINE_JUDGE
freopen("in.cpp","r",stdin);
#endif // ONLINE_JUDGE
int i,n,j,k,_T;
while(scanf("%d",&n)==1){
for(i=1;i<=n;i++)scanf("%d",&a[i]);
vector<int>L;
for(i=1;i<=n;i++){
int id=std::lower_bound(L.OP,L.ED,a[i])-L.OP;
if(id==L.SZ)L.PB(a[i]);
else L[id]=a[i];
}
printf("%d\n",L.SZ);
}
return 0;
}
用nlogn 解决最长递增子序列。
将求最长公共子序列转化为求最长递增子序列
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=65000;
const int inf=1000000000;
int A[maxn];
int B[maxn];
int C[maxn];
int D[maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.cpp","r",stdin);
#endif // ONLINE_JUDGE
int t;
cin>>t;
int Cas=0;
while(t--)
{
int n,p,q;
scanf("%d%d%d",&n,&p,&q);
int x;
memset(A,0,sizeof(A));
for(int i=1;i<=p+1;i++)
{
scanf("%d",&x);
A[x]=i;
}
int y;
int s=0;
for(int i=1;i<=q+1;i++)
{
scanf("%d",&y);
if(A[y]) B[s++]=A[y];
}
for(int i=0;i<=s;i++) C[i]=inf;
int ans=0,k;
for(int i=0;i<s;i++)
{
k=lower_bound(C+1,C+s,B[i])-C;
D[i]=k;
C[k]=B[i];
ans=max(ans,D[i]);
}
printf("Case %d: %d\n",++Cas,ans);
}
}
3. poj 1458 Longest Common Subsequence
最长公共子序列:
状态转移: if(str1[i-1]==str2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
const int maxn=305;
string str1,str2 ;
int dp[maxn][maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.cpp","r",stdin);
#endif // ONLINE_JUDGE
int h1,h2;
while(cin>>str1>>str2)
{
h1=str1.size();
h2=str2.size();
memset(dp,0,sizeof(dp));
for(int i=1; i<=h1; i++)
{
for(int j=1; j<=h2; j++)
{
if(str1[i-1]==str2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
printf("%d\n",dp[h1][h2]);
getchar();
}
return 0;
}</span>