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;

}

 

你可能感兴趣的:(codeforces)