easy dp

1.将一堆正整数分为2组,要求2组的和相差最小。

                                            
  //File Name: nod1007.cpp
  //Author: long
  //Mail: 736726758@qq.com
  //Created Time: 2016年05月28日 星期六 20时12分23秒
                                   

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>

using namespace std;

bool f[101][10001];
int a[101];

void solve(int n){
    memset(f,false,sizeof f);
    f[0][0] = true;
    int now = 0;
    for(int i=1;i<=n;i++){
        now += a[i];
        for(int j=0;j<=now;j++){
            f[i][j] = f[i-1][j];
            if(j >= a[i]) f[i][j] |= f[i-1][j-a[i]];
        }
    }
    int ans = 100000;
    for(int i=0;i<=now;i++){
        if(!f[n][i]) continue;
        ans = min(ans,abs(now - 2 * i));
    }
    printf("%d
",ans);
}

int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        solve(n);
    }
    return 0;
}
View Code

2.最长递增子序列

                                            
  //File Name: nod1134.cpp
  //Author: long
  //Mail: 736726758@qq.com
  //Created Time: 2016年05月28日 星期六 20时45分45秒
                                   

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>

using namespace std;

const int MAXN = 50000 + 5;
const int INF = 0x3f3f3f3f;

int d[MAXN];
int a[MAXN];

int bs(int l,int r,int x){
    int mid;
    while(r - l > 1){
        mid = (l + r) >> 1;
        if(d[mid] < x) l = mid;
        else r = mid;
    }
    return l;
}

int solve(int n){
    int len = 0;
    d[0] = -INF;
    for(int i=1,j;i<=n;i++){
        if(a[i] > d[len]){
            d[++len] = a[i];
        }
        j = bs(0,len,a[i]);
        d[++j] = a[i];
    }
    return len;
}

int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        printf("%d
",solve(n));
    }
    return 0;
}
View Code

3.最大子矩阵和

一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值

                                            
  //File Name: nod1051.cpp
  //Author: long
  //Mail: 736726758@qq.com
  //Created Time: 2016年05月28日 星期六 21时22分03秒
                                   

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>

#define LL long long

using namespace std;

const int MAXN = 501;

LL b[MAXN],f[MAXN];
int a[MAXN][MAXN];

LL get(int n){
    LL ans = 0;
    f[0] = 0;
    for(int i=1;i<=n;i++){
        f[i] = max(f[i-1],0LL) + b[i];
        if(f[i] > ans) ans = f[i];
    }
    return ans;
}

LL solve(int n,int m){
    LL ans = -1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) b[j] = 0;
        for(int j=i;j<=n;j++){
            for(int k=1;k<=m;k++)
                b[k] = b[k] + a[j][k];
            LL now = get(m);
            if(now > ans) ans = now;
        }
    }
    return ans;
}

int main(){
    int n,m;
    while(~scanf("%d %d",&m,&n)){
        bool flag = false;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
                if(a[i][j] >= 0) flag = true;
            }
        }
        if(!flag) puts("0");
        else printf("%lld
",solve(n,m));
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/-maybe/p/5538371.html