1、LCS(最长公共子序列)
B - Common Subsequence
subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, …, xm > another sequence Z = < z1, z2, …, zk > is a subsequence of X if there exists a strictly increasing sequence < i1, i2, …, ik > of indices of X such that for all j = 1,2,…,k, x
ij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
Input
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.
Output
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
#include<stdio.h>
#include<string.h>
int dp[1005][1005];
char a[1005],b[1005];
int ma(int a,int b,int c){
int tem=a;
if(b>=a) tem=b;
if(tem>=c) return tem;
else return c;
}
int main(){
while(scanf("%s %s",a,b)!=EOF){
memset(dp,0,sizeof(dp));
int l=strlen(a);
int k=strlen(b);
for(int i=1;i<=l;i++){
for(int j=1;j<=k;j++){
if(a[i-1]==b[j-1]) dp[i][j]=ma(dp[i-1][j-1]+1,dp[i][j-1],dp[i-1][j]);
else dp[i][j]=ma(dp[i-1][j],dp[i][j-1],0);
}
}
printf("%d\n",dp[l][k]);
}
}
2、LIS(最长上升子序列)
f[i]=max(f[j]+1) {j=1、2、3……i-1}
3、数字三角形
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
(Figure 1)
Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.
Input
Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.
Output
Your program is to write to standard output. The highest sum is written as an integer.
Sample Input5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
#include <stdio.h>
#include <algorithm>
using namespace std;
int a[101][101];
int main(){
int i,n,j,k;
scanf("%d",&n);
for( i = 0; i < n; i++ )
for( j = 0; j <= i;j++ ){
scanf("%d",&a[i][j]);
}
for( i--; i >= 0; i-- )
for( j=0; j <= i; j++ ){
a[i][j] += max(a[i+1][j],a[i+1][j+1]);
}
printf("%d\n",a[0][0]);
}
4、01背包
从N个物品中选择一些物品进入背包,背包体积为V,每个物品都有其自身的价值和体积,要求不超过背包体积的情况下,价值最大。
int main(){
while(scanf("%d %d",&n,&m)!=EOF){
for(int i=0;i<n;i++) scanf("%d %d",&w[i],&d[i]);
memset(s,0,sizeof(s));
for(int i=0;i<n;i++)
for(int j=m;j>=w[i];j--)
s[j]=ma(s[j],s[j-w[i]]+d[i]);
ans=0;
for(int i=1;i<=m;i++) ans=ma(ans,s[i]);
printf("%d\n",ans);
}
return 0;
}
5、完全背包
与01背包不同的是,01背包每个物品只能选择一次,而完全背包每个物品可以选择无数次,把01背包循环的逆序改成正序即可。
for(int i=0;i<n;i++)
for(int j=w[i];j<=m];j++)
s[j]=ma(s[j],s[j-w[i]]+d[i]);
6、多重背包
与01背包不同的是,每种物品可以选择限定的次数,用二进制拆分成01背包或者单调队列来做、
///拆分过程
scanf("%d %d",&num,&val);
int i=1,cnt=0;
while(num>=i){
s[cnt++]=i*val;
num-=i;
i*=2;
}
s[cnt++]=num*val;
7、分组背包
与01背包不同的是,给你n组,第i组有ai个物品,要求你每组最多选一个,是背包的价值最大。
for(int i=1;i<=n;i++)//第i组
for(int j=m;j>=0;j--)//背包容量
for(int k=1;k<=c[i];k++)//第i组的所有物品
//必须把k放在内层,不然不是分组背包
if(j>=k)
dp[j]=ma(dp[j],dp[j-k]+w[i][k]);
8、背包组合
四种背包的组合问题。