理解动态规划的基础
一、求最长递增子序列的函数:
int LIS(int *dp,int *a,int n){
int maxlen=0;
for (int i = 0; i < n; i++) {
int len= 1;
for (int j = 0; j<i; j++)
if (a[j]<a[i]) {
len = max(len,dp[j]+1);
}
dp[i]=len;
maxlen=max(dp[i],maxlen);
}
return maxlen;
}
int LIS(int *a,int t) {
int dp[maxn];
int len;
dp[1] = a[1];
len = 1;
for (int i = 2 ; i <= t ; i++) {
if (a[i] > dp[len]) {
dp[++len] = a[i];
continue;
}
int l = 1 ,r = len,mid;
while(l < r) {
mid = (l + r) / 2;
if(dp[mid] < a[i])
l = mid + 1 ;
else
r = mid;
}
dp[l] = a[i];
}
return len;
}
二、求最大递增子序列的函数:(借用了最长递增子序列的思想)
int BIS(int *dp,int *a,int n){
int maxsum=0;
int sum;
for (int i = 0; i < n; i++) {
sum=a[i];
for (int j = 0; j<i; j++)
if (a[j]<a[i]) {
sum= max(sum,dp[j]+a[i]);
}
dp[i]=sum;
if(dp[i]>maxsum)
maxsum=dp[i];
}
return maxsum;
}
三、求最长公共子序列函数:(第一个仅求长度,第二个求具体内容)
void lcs(int i, int j){
for(i=1; i<=len1; i++){
for(j=1; j<=len2; j++){
if(a[i-1] == b[j-1])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j],dp[i][j-1])
}
}
}
void llcs(){
int i, j, z = 0;
char c[1001];
memset(c, 0, sizeof(c));
i = len1, j = len2;
while(i!=0 && j!=0)
{
if(a[i-1] == b[j-1])
{
c[z++] = a[--i];
j--;
}
else if(dp[i-1][j] < dp[i][j-1])
j--;
else if(dp[i-1][j] >= dp[i][j-1])
i--;
}
for(i=z-1; i>=0; i--)
printf("%c", c[i]);
printf("\n");
}