easy dp

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

  //File Name: nod1007.cpp
  //Author: long
  //Mail: [email protected]
  //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\n",ans);
}

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

2.最长递增子序列

  //File Name: nod1134.cpp
  //Author: long
  //Mail: [email protected]
  //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\n",solve(n));
    }
    return 0;
}

3.最大子矩阵和

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

  //File Name: nod1051.cpp
  //Author: long
  //Mail: [email protected]
  //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\n",solve(n,m));
    }
    return 0;
}

时间: 2024-10-29 19:12:27

easy dp的相关文章

Boredom easy dp

Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 455A Description Alex doesn't like boredom. That's why whenever he gets bored, he comes up with games. One long winter evening he came up

BZOJ 3450: Tyvj1952 Easy [DP 概率]

传送门 题意:$ox?$组成的序列,$?$等概率为$o\ or\ x$,得分为连续的$o$的长度的平方和,求期望得分 一开始没想出来,原因在于不知道如何记录长度 其实我们同时求得分和长度的期望就好了 $(x+1)^2=x^2+2x+1$ 其实就是维护了$x$的期望和$x^2$的期望 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include &l

【dp入门题】【跟着14练dp吧...囧】

A HDU_2048 数塔 dp入门题——数塔问题:求路径的最大和: 状态方程: dp[i][j] = max(dp[i+1][j], dp[i+1][j+1])+a[i][j];dp[n][j] = a[n][j]; 其中dp[i][j]: 深度为i的第j个结点的最大和; 1 /* 2 Problem: HDU-2048 3 Tips: Easy DP 4 dp[i][j]: 深度为i的第j个结点的最大和: 5 dp[i][j] = max(dp[i+1][j], dp[i+1][j+1])+

EOJ Monthly 2018.1 F 最小OR路径

题目链接 Description 给定一个有 \(n\) 个点和 \(m\) 条边的无向图,其中每一条边 \(e_i\) 都有一个权值记为 \(w_i\) . 对于给出的两个点 \(a\) 和 \(b\) ,求一条 \(a\) 到 \(b\) 的路径,使得路径上的边权的 \(OR\)(位或)和最小,输出这个值.(也就是说,如果将路径看做边的集合 \(\{e_1,e_2,-,e_k\}\),那么这条路径的代价为 \(w_1\ OR\ w_2\ OR\ -\ OR\ w_k\),现在求一条路径使得其

EOJ Monthly 2018.2

A. 坑爹的售票机 题意 用\(1,5,10,25,50,100\)的纸币买\(n\)张单价为\(p\)的船票,且一次性最多买\(k\)张,求钱数恰好时最少需要多少张纸币. Hard: \(n,k,p\leq 10^9\) 思路 Easy: dp Hard: dp + 瞎搞 当钱数过大或者张数过多时,(由直觉)其中的大部分都是遵循一定的规律来取的,只有剩余的一小部分需要dp. Code Easy #include <bits/stdc++.h> #define F(i, a, b) for (

20191230-20200102总结(1)

LeetCode66. Plus One - Easy LeetCode67. Add Binary - Easy LeetCode69. Sqrt(x) - Easy 二分找 LeetCode70. Climbing Stairs - Easy dp LeetCode71. Simplify Path - Medium Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert

HDU 4359 Easy Tree DP?

Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1487    Accepted Submission(s): 567 Problem Description A Bear tree is a binary tree with such properties : each node has a value o

zoj 3791 An Easy Game dp

An Easy Game Time Limit: 2 Seconds      Memory Limit: 65536 KB One day, Edward and Flandre play a game. Flandre will show two 01-strings s1 and s2, the lengths of two strings are n. Then, Edward must move exact k steps. In each step, Edward should ch

ZOJ3802 Easy 2048 Again (状压DP)

ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5334 Easy 2048 Again Time Limit: 2 Seconds      Memory Limit: 65536 KB Dark_sun knows that on a single-track road (which means once he passed this