LoginSignup
0
0

More than 3 years have passed since last update.

Educational DP ContestのB問題, C問題

Posted at

レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】

前回の続き

全探索:全列挙, 工夫して通り数を減らす全列挙, ビット全探索

解説

動的計画法超入門! Educational DP Contest の A ~ E 問題の解説と類題集

B問題

B - Frog 2

A問題との違いは、分岐パターンが変数になった事です。
簡単ですね。

C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cctype>

#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9

using namespace std;
using ll =long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
const long long INF = 1LL << 60;

ll dp[100002];
int H[100002];

int main(int argc, const char * argv[]) {
    int N, K;
    cin >> N >> K;

    rep(i, N+2) dp[i] = INF;
    rep(i, N) cin >> H[i];

    dp[0] = 0;

    for(int i=1; i<N; i++){
        for(int j=1; j<=K; j++){
            if(i-j>=0) chmin(dp[i], dp[i-j] + abs(H[i]-H[i-j]));
        }
    }
    cout << dp[N-1] << endl;

    return 0;
}

C - Strange Bank

dpデーブルを使わないdp

貪欲法だと、
14-9=5みたいな結果の際に、6回の引き出しが必要。
14-6=8、8-6=2で4回の引き出しになり9を使用した時より少ない。
つまり貪欲法が使えない。

その為、6を使用する金額、9を使用する金額を分ける全探索をとります。
0~iまでの金額を6に使用します。
N-iの金額を9に使用します。

そうすると16、17みたいな金額は、6まで6を使用(16−6=10)。
10−9=1で3回の引き出し回数を導き出すことができます。

C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cctype>

#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9

using namespace std;
using ll =long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
const long long INF = 1LL << 60;

int main(int argc, const char * argv[]) {
    int N;
    cin >> N;

    int res = N;
    for(int i=0; i<=N; i++){
        int cc=0;
        int t=i;
        while(t>0){ cc+=t%6; t/=6; }
        t = N - i;
        while(t>0){ cc+=t%9; t/=9; }
        if(res>cc) res = cc;
    }
    cout << res << endl;

    return 0;
}

C問題

C - Vacation

C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cctype>

#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9

using namespace std;
using ll =long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
const long long INF = 1LL << 60;

ll dp[100002][3];
ll A[100002][3];



int main(int argc, const char * argv[]) {
    int N;
    cin >> N;

    rep(i, N) cin >> A[i][0] >> A[i][1] >> A[i][2];

    for(int i=0; i<N; i++){
        for(int j=0; j<3; j++){
            for(int k=0; k<3; k++){
                if(j==k) continue;
                chmax(dp[i+1][k], dp[i][j] + A[i][k]);
            }
        }
    }

    ll res=0;
    rep(i, 3) res = max(res, dp[N][i]);
    cout << res << endl;

    return 0;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0