@一句话题解@

目录

  • @2019.12@

@2019.12@

topcoder - SRM765Round1 D1L3:只有单位代价最大的才可能不全选完,所以按单位代价排序然后从小到大作个背包即可。

#include 
#include 
#include 
using namespace std;
typedef long long ll;
class SteelMill{
    private:
        #define MAXN 100
        #define MAXM 1000000
        #define INF (1LL<<60)
        struct node{
            int siz; ll spc, kgc;
            node(int _s=0, int _sc=0, int _kc=0) : siz(_s), spc(_sc), kgc(_kc) {}
            friend bool operator < (node a, node b) {
                return a.kgc < b.kgc;
            }
        }a[MAXN + 5];
        ll f[MAXM + 5]; int n;
    public:
        ll cheapest(int goal, vectorshipmentCost, vectorshipmentSize, vectorcostPerKg) {
            n = shipmentCost.size();
            for(int i=0;i=goal-a[i].siz&&j>=0;j--)
                    t += a[i].kgc, ans = min(ans, f[j] + t);
                for(int j=goal-1;j>=a[i].siz;j--)
                    f[j] = min(f[j], f[j-a[i].siz] + c);
            }
            return ans;
        }
};

topcoder - TCO19JapanRegionalRound D1L2:类比卡特兰数看成 H*A 的方格恰好 C 次穿过 y = x 这条线,然后直接 dp[H][A][C],转移枚举下一次在哪里穿过然后乘个卡特兰数。|H-A|总为定值所以记忆化搜索。

#include 
#include 
#include 
using namespace std;
class ChangesInTheLead{
    #define MOD 1000000007
    #define MAXN 250
    public :
    int c[2*MAXN + 5][2*MAXN + 5], f[MAXN + 5][MAXN + 5];
    void init() {
        for(int i=0;i<=2*MAXN;i++) {
            c[i][0] = 1;
            for(int j=1;j<=i;j++)
                c[i][j] = (c[i-1][j] + c[i-1][j-1]) % MOD;
        }
        for(int i=0;i<=MAXN;i++) {
            for(int j=0;j<=i;j++)
                f[i][j] = (c[i+j][i] + MOD - c[i+j][i+1]) % MOD;
        }
        f[0][0] = 0;
    }
    int dp[MAXN + 5][MAXN + 5][MAXN + 5];
    int get(int A, int B, int C) {
        if( dp[A][B][C] != -1 ) return dp[A][B][C];
        if( C == 0 ) return dp[A][B][C] = f[A][B];
        dp[A][B][C] = 0;
        for(int i=1;i<=A&&i<=B;i++)
            dp[A][B][C] = (dp[A][B][C] + 1LL*get(B - i, A - i, C - 1)*f[i][i]%MOD) % MOD;
        return dp[A][B][C];
    }
    int count(int H, int A, int C) {
        init(); memset(dp, -1, sizeof dp);
        if( H == 0 && A == 0 && C == 0 ) return 1;
        else return (get(H, A, C) + get(A, H, C)) % MOD;
    }
};

topcoder - 2017TCOAlgorithmFinal D1L2:忽略空位,结论是对于 ABA....BA 这种交替出现(要求极长,即不能再往外延伸)的段,只有最后一个字符对应的玩家才会移动这个段中的棋子。因此直接从后往前 dp,记录两个玩家能够移动的步数之差。

#include 
#include 
using namespace std;
class GameOfTokens{
    private :
    #define MOD 1000000007
    #define MAXN 50
    #define MAXM 2500
    bool flag;
    int f[2][MAXN + 5][2*MAXM + 5];
    int t[2][MAXN + 5][2*MAXM + 5];
    int n, m;
    void get_temp() {
        for(int i=0;i<=n;i++)
            for(int j=0;j<=2*m;j++) {
                t[0][i][j] = f[0][i][j], f[0][i][j] = 0;
                t[1][i][j] = f[1][i][j], f[1][i][j] = 0;
            }
    }
    void trans(int op) {
        if( op == -1 ) {
            for(int i=0;i<=n;i++)
                for(int j=0;j<=2*m;j++) {
                    if( j + i <= 2*m )
                        f[0][i][j+i] = (f[0][i][j+i] + t[0][i][j]) % MOD;
                    if( j - i >= 0 )
                        f[1][i][j-i] = (f[1][i][j-i] + t[1][i][j]) % MOD;
                }
        }
        else {
            if( flag ) {
                f[op][1][m] = (f[op][1][m] + 1) % MOD;
            }
            for(int i=0;i<=n;i++)
                for(int j=0;j<=2*m;j++) {
                    if( i + 1 <= n )
                        f[op][i+1][j] = (f[op][i+1][j] + t[op][i][j]) % MOD;
                    if( i )
                        f[op][0][j] = (f[op][0][j] + t[!op][i][j]) % MOD;
                }
            for(int j=0;j<=2*m;j++) {
                f[op][1][j] = (f[op][1][j] + t[!op][0][j]) % MOD;
            }
        }
    }
    public :
    int count(string pattern) {
        n = pattern.size(), m = n*n;
        flag = true;
        for(int i=n-1;i>=0;i--) {
            get_temp();
            if( pattern[i] == '?' )
                trans(0), trans(1), trans(-1);
            else if( pattern[i] == '.' )
                trans(-1);
            else trans(pattern[i] - 'A'), flag = false;
        }
        int ans = 0;
        for(int i=m+1;i<=2*m;i++)
            for(int j=0;j<=n;j++)
                ans = (ans + (f[0][j][i] + f[1][j][i]) % MOD) % MOD;
        return ans;
    }
};

你可能感兴趣的:(@一句话题解@)