最大子矩阵和
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=500+10;
int f[maxn],c[maxn][maxn],d[maxn];
int main()
{
int m,n,ans=0,sum=0,b=0;
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&c[i][j]);
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
for(int k=1;k<=m;k++)
f[k]=(i==j)?c[i][k]:(f[k]+c[j][k]);
b=0;
// for(int k=1;k<=m;k++) cout<<f[k]<<" ";cout<<endl;
for(int k=1;k<=m;k++)
{
if(b>0) b+=f[k];
else b=f[k];
sum=max(sum,b);
}
// cout<<sum<<endl;
ans=max(ans,sum);
}
}
printf("%d\n",ans);
return 0;
}
循环数组最大子段和#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000+10;
int f[maxn];
int main()
{
int n;
long long maxx=-100000000,minn=100000000,a=0,b=0,sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&f[i]);
sum+=f[i];
}
for(int i=1;i<=n;i++)
{
if(a>0) a+=f[i];
else a=f[i];
maxx=max(maxx,a);
}
for(int i=1;i<=n;i++)
{
if(b<0) b+=f[i];
else b=f[i];
minn=min(minn,b);
}
sum=max(maxx,sum-minn);
printf("%lld\n",sum);
return 0;
}
多重背包问题#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50000+10;
int n,v;
int w[105],p[105],c[105];
int f[maxn];
int main()
{
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&w[i],&p[i],&c[i]);
for(int i=1;i<=n;i++)
{
int t=c[i],k=1;
while(t>k)
{
for(int j=v;j>=k*w[i];j--)
f[j]=max(f[j],f[j-k*w[i]]+k*p[i]);
t-=k;
k*=2;
}
for(int j=v;j>=t*w[i];j--)
f[j]=max(f[j],f[j-t*w[i]]+t*p[i]);
}
printf("%d\n",f[v]);
return 0;
}
更难的矩阵取数问题#include <iostream>
#include<stdio.h>
#include <string.h>
using namespace std;
int dp[405][205][205];
int a[205][205];
int main()
{
int n,m;
while(~scanf("%d%d",&m,&n))
{
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
scanf("%d",&a[i][j]);
memset(dp,0,sizeof(dp));
for(int k=2; k<=n+m; k++)
{
for(int i=1; i<=n&&k-i>=1; i++)
{
for(int j=1; j<=n&&k-j>=1; j++)
{
dp[k][i][j]=max( dp[k][i][j],dp[k-1][i-1][j-1]+a[i][k-i]+(i==j?0:a[j][k-j]));
dp[k][i][j]=max(dp[k][i][j],dp[k-1][i][j-1]+a[i][k-i]+(i==j?0:a[j][k-j]));
dp[k][i][j]=max(dp[k][i][j],dp[k-1][i-1][j]+a[i][k-i]+(i==j?0:a[j][k-j]));
dp[k][i][j]=max(dp[k][i][j],dp[k-1][i][j]+a[i][k-i]+(i==j?0:a[j][k-j]));
}
}
}
cout<<dp[n+m][n][n]<<endl;
}
return 0;
}
最长单增子序列#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50000+10;
int f[maxn],a[maxn];
int n;
int Binarysearch(int low,int high,int x)
{
int mid=0;
while(low<=high)
{
mid=(low+high)/2;
if(f[mid]<x&&f[mid+1]>=x)
return mid;
else if(f[mid]<x)
low=mid+1;
else
high=mid-1;
}
return 0;
}
int LIS()
{
int len=1,p;
f[1]=a[1];
for(int i=2;i<=n;i++)
{
if(a[i]>f[len])
p=++len;
else
p=Binarysearch(1,len,a[i])+1;
f[p]=a[i];
}
return len;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("%d\n",LIS());
return 0;
}
子序列的个数#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000+10;
int f[maxn],a[maxn],have[maxn];
#define mod 1000000007
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
memset(have,0,sizeof(have));
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1;i<=n;i++)
{
if(!have[a[i]]) f[i]=(f[i-1]*2)%mod;
else f[i]=(f[i-1]*2%mod-f[have[a[i]]-1]+mod)%mod;
have[a[i]]=i;
}
printf("%d\n",(f[n]-1));
return 0;
}