AtCoder 초보자 대회 145

로그인합니다.

B - 에코

서명합니다.

C - 평균 길이

카드 정확성에 자신 또는 긴 더블 아웃 양자 캐리를 사용하여.


암호

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/16 20:04:44
 */
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 10;
const double eps = 1e-6;
int n;
struct Point{
    int x, y;   
}p[N];
int a[N];
double dis(Point A, Point B) {
    double tmp = 1.0 * (A.x - B.x) * (A.x - B.x) + 1.0 * (A.y - B.y) * (A.y - B.y);   
    double l = 0, r = tmp, mid;
    for(int i = 1; i <= 500; i++) {
        mid = (l + r) / 2;
        if(mid * mid < tmp) l = mid;
        else r = mid;   
    }
    return r;
}
void run(){
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> p[i].x >> p[i].y;
    for(int i = 1; i <= n; i++) a[i] = i;
    double ans = 0;
    int tot = 0;
    do {
        ++tot;
        for(int i = 2; i <= n; i++) {
            ans += dis(p[a[i]], p[a[i - 1]]);
        }
    } while(next_permutation(a + 1, a + n + 1));
    ans = ans / tot;
    cout << ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}

D - 기사

질문의 의미 :
에있는 전당포가 있습니다 \ ((0,0) \) 돌가에 위치한 점, \ ((I, J) \ ) , 당신은 이동할 수 있습니다 \ ((내가 + 1, J (+ 2) + 2, J + 1) \ ) 이 두 셀.
Q. 얼마나 많은 다른 방법으로 할 수있는 점 \ ((X 축의 y 축) \) .

아이디어 :
이후 \ (X 축의 Y- \ LEQ 10 ^ 6 \) , 분명히 직접 \ (DP \) 할 수 없습니다.
그리고 우리는 그것을 시뮬레이션 끝에서 다시 뛰어 결국 사면의 복수를 형성 발견, 법을 찾을 \ (1 \)를 직선 조합의 수 위의 모든 관련 포인트 점프 직선에 응답합니다.
이어서 최종 것으로 \ ((0,0) \) 층으로 가리 \ (\ FRAC {X} + {Y}. 3 \) , 최종 응답이 \ (\ FRAC {X + Y가 } {3} 선택 \ t \) .
종이에 대한 세부 사항은 무엇 나왔다.


암호

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/16 20:26:13
 */
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e6 + 15, MOD = 1e9 + 7;

int fac[N];

ll qpow(ll a, ll b) {
    ll ans = 1;
    while(b) {
        if(b & 1) ans = ans * a % MOD;
        a = a * a % MOD;
        b >>= 1;   
    }
    return ans;   
}

int C(int n, int m) {
    return 1ll * fac[n] * qpow(fac[n - m], MOD - 2) % MOD * qpow(fac[m], MOD - 2) % MOD;
}

void run(){
    fac[0] = 1;
    for(int i = 1; i < N; i++) fac[i] = 1ll * fac[i - 1] * i % MOD;
    int x, y;
    cin >> x >> y;
    if((x + y) % 3 != 0) {
        cout << 0;
        return;
    }
    int t = (x + y) / 3;
    if(y - t >= 0 && y - t <= t) {
        cout << C(t, y - t);
    } else cout << 0;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}

E - 음식 뷔페

질문의 의미 :
지금이 \ (n \) 요리를, 각 요리의 요구 \ (A_I \) 시간이 먹고 (\ b_i) \ 맜있는의.
다음과 같은 규칙이 있습니다 :

  • 접시의 시점 후, 당신은 단지 식사 후 다음 접시를 가리 키도록 할 수 있습니다.
  • \ (T \) 주문을받을 수 없어,하지만 여전히 물린 수있는 시간 후.
  • 매 시점 번 야채.

마지막으로 마지막으로 최대의 맛을이 얻을 수있을 물었다.

아이디어 :

  • 더 중요한 것은, 아니 마지막 순서가 일품 무엇인지는 중요합니다, 우리는 준비 접시의 확신 할 수 \ (T \) 지점 시간.
  • 문제는 매우 간단해진다 그래서 후 : 총 \ (T-1 \) 시간, 배낭, 다음의 상응하는 직접 \ (DP \) 필요 \ (O (N- 형 ^ 2) \) .
  • 전체 복잡하므로 그러나 우리는 마지막 지점에서 어떤 요리를 열거 할 필요가 \ (O (N ^ 3) \) 분명히 용납 할 수없는 시간의 복잡성.
  • 우리가 유일한 관심사는 한 접시되지 투표이기 때문에, 우리가 접하기 전에 전처리 할 수있다 \ (DP \) , \ (DP1 [I] [J]가 \) 대표 \ (1 \) ~ \ (I \) 문서는 전체 시간이되지 않는 초과 \ (J는 \) 맛의 최대 정도이다 \ (DP2은 [I] [J] \) 유사.
  • 최종 시간 복잡도는 \ (O (N ^ -2) \) .

직접 질문은 제한 시간을 초과 할 수 있기 때문에 나쁜 상태의 정의, 그래서이 작업을 수행 할 수 있지만, 마지막 제국의 위치 문제 후 변환되었습니다.
접두사와 접미사 \ (DP는 \) 전처리는 아주 똑똑 QAQ입니다.


암호

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/18 15:30:25
 */
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 3005;

int n, t;
int a[N], b[N];
int dp1[N][N], dp2[N][N];

void run(){
    for(int i = 1; i <= n; i++) cin >> a[i] >> b[i];
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= t - 1; j++) {
            dp1[i][j] = dp1[i - 1][j];
            if(j >= a[i]) 
                dp1[i][j] = max(dp1[i][j], dp1[i - 1][j - a[i]] + b[i]);
        }   
    }
    for(int i = n; i >= 1; i--) {
        for(int j = 1; j <= t - 1; j++) {
            dp2[i][j] = dp2[i + 1][j];
            if(j >= a[i])
                dp2[i][j] = max(dp2[i][j], dp2[i + 1][j - a[i]] + b[i]);   
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++) {
        for(int j = 0; j <= t - 1; j++) {
            ans = max(ans, dp1[i - 1][j] + dp2[i + 1][t - 1 - j] + b[i]);
        }   
    }
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> t) run();
    return 0;
}

 
문제는 더 미묘한 해결책이 : 우리가 접시의 마지막 포인트는 다음 분명히 우리는 항상 가장 시간이 많이 걸리는 준비 넣어 알고 가정 \ (T을 \) 지점으로 시간을.
그리고 추가 질문으로 전환 : 마지막 하나를 골라 가정하면, 이전은이보다 더 소요 선택합니다.
따라서, 상기 공정에 직접 \ (DP1 [I] [J] \) , 서 픽스에 대한 최대 값을 유지하면서.


암호

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/18 15:30:25
 */
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 3005;

int n, t;
struct node {
    int a, b;   
    bool operator < (const node &A) const {
        return a < A.a;   
    }
}p[N];
int maxv[N];
int dp[N][N];

void run(){
    for(int i = 1; i <= n; i++) cin >> p[i].a >> p[i].b;
    sort(p + 1, p + n + 1);
    for(int i = n; i >= 1; i--) maxv[i] = max(maxv[i + 1], p[i].b);
    int ans = 0;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= t - 1; j++) {
            dp[i][j] = dp[i - 1][j];
            if(j >= p[i].a) dp[i][j] = max(dp[i][j], dp[i - 1][j - p[i].a] + p[i].b);
        }
        ans = max(ans, dp[i][t - 1] + maxv[i + 1]);
    }
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> t) run();
    return 0;
}

F - 라미네이트

문제의 의미
가있다 \ N- (\) 열 번째 행과 각 열에 높이 갖는다 (\. H_i 0 \ 당량 H_i \ 당량 9 ^ 10 \) .
대부분에 있습니다 (\ K) \ 일부가 임의로 컬럼의 높이를 수정의 기회.
수행 한 후 작업 : 연속 컬럼에 대해 횡 방향으로 서로를 소거. 동작 Q. 최종 최소 수이다.

아이디어 :
이 제목이 555 ... 너무 많은 음식 아이디어을 직접 아무 느낌이 없다.
많은 경우를 고려, 매우 추상적 인 문제를 느껴, 일반적인 느낌이 문제를 시각화, 콘크리트는 제목, 우리가 고려로 해결하는 문제의 핵심입니다 (K = 0 \) \ 최종 대답은 경우 :
\ [\ sum_ {난 = 1}
^ 최대 {N} (0 h_i-H_는 {I-1}) \] 다음 결론있다 : 만약 열을 수정하는 경우, 그 위치를 추정한다 (I는 \) \ 최종이어서, 높이 (\ [H_ {I-1 }, {H_ I + 1}] \) 최적 사이.

이 결론은 우리가 할 수있는, 더 명확하게 직접 제국이다 : 수정 작업을하고 경우에도 (. H_i = H_-I 1} {\) \ .
또한, 관찰 작업은 열을 삭제 동등하다 볼 수있다.

이 때의 용액에 대조에서는 수 (DP는 [I] [J \ ] \) 전 나타낸다 \ (I \) 기둥 예약 \ (J \) 작업 루트 최소 번호.
그런 전이 : \ (DP [I] [J] = 분 \ {DP [K]. -J 1] + (최대 0 H_i-h_k) J <I \} \) .
직접 \ (O (N ^ 3) \) 자신의 사라 실시한다.

PS :이 나중 일 수있다 (\ 최대) \ 어레이를 최적화하기 위해 열 및 트리에서 두 값을 유지하도록 동작하며, 복잡도가 달성 될 수있다 (O (N ^ 2logn) \ \)


암호

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/18 18:16:10
 */
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 300 + 5;

int n, K;

int h[N];
ll dp[N][N];

void run(){
    for(int i = 1; i <= n; i++) cin >> h[i];
    memset(dp, INF, sizeof(dp));
    dp[0][0] = 0;
    for(int i = 1; i <= n - K; i++) {
        for(int j = i; j <= n; j++) {
            for(int k = 0; k < j; k++) {
                dp[j][i] = min(dp[j][i], dp[k][i - 1] + max(0, h[j] - h[k]));   
            }
        }   
    }
    ll ans = INF;
    for(int i = 1; i <= n; i++) ans = min(ans, dp[i][n - K]);
    if(ans == INF) ans = 0;
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> K) run();
    return 0;
}

추천

출처www.cnblogs.com/heyuhhh/p/11887825.html