CodeForces 294B Shaass and Bookshelf 【规律 & 模拟】或【Dp】

这道题目的意思就是排两排书,下面这排只能竖着放,上面这排可以平着放,使得宽度最小

根据题意可以得出一个结论,放上这排书的Width 肯定会遵照从小到大的顺序放上去的

Because the total thickness of vertical books is fixed it's good to calculate the minimum possible total width of horizontal books. 

那么只需要模拟一遍放书的过程即可,不会TLE

 

不过正统解法是Dp

Dp Source Code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-7      ;
const int N = 210            ;
const int M = 1100011*2      ;
const ll P = 10000000097ll   ;
const int MAXN = 10900000    ;
const int INF = 0x3f3f3f3f   ;

int dp[101][210][301];

int main(){
    std::ios::sync_with_stdio(false);
    int i, j, t, k, u, v, x, y, numCase = 0;
    int n, a, b;
    dp[0][0][0] = 1;
    cin >> n;
    int cur = 0;
    for(i = 0; i < n; ++i){
        cin >> a >> b;
        for(j = 0; j < cur + 1; ++j){
            for(k = 0; k < 201; ++k){
                dp[i + 1][j + a][k] |= dp[i][j][k];
                dp[i + 1][j][k + b] |= dp[i][j][k];
            }
        }
        cur += a;
    }
    for(i = 0; i < 201; ++i){
        for(j = 0; j < i + 1; ++j){
            if(dp[n][i][j]){
                cout << i << endl;
                return 0;
            }
        }
    }

    return 0;
}

My Source Code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-7      ;
const int N = 210            ;
const int M = 1100011*2      ;
const ll P = 10000000097ll   ;
const int MAXN = 10900000    ;
const int INF = 0x3f3f3f3f   ;

int a[10][122];
int one, two, n;

int main(){
    std::ios::sync_with_stdio(false);
    int i, j, t, k, u, v, x, y, numCase = 0;
    cin >> n;
    for(u = 0; u < n; ++u){
        cin >> x >> y;
        if(x == 1){
            a[1][one++] = y;
        } else{
            a[2][two++] = y;
        }
    }
    sort(a[1], a[1] + one);
    sort(a[2], a[2] + two);
    int ans = INF;
    for(i = 0; i <= one; ++i){
        for(j = 0; j <= two; ++j){
            int cur = 0;
            for(k = 0; k < one - i; ++k){
                cur += a[1][k];
            }
            for(k = 0; k < two - j; ++k){
                cur += a[2][k];
            }
            if((i + 2 * j) < ans && (i + 2 * j) >= cur){
                ans = i + 2 * j;
            }
        }
    }
    cout << ans << endl;

    return 0;
}
原文地址:https://www.cnblogs.com/wushuaiyi/p/4314285.html