최대 여기서 LuoGu] P1018 제품

\ (\ 컬러 {빨간색} {\ mathcal {설명}} \)

올해는 "결정하기 위해 국제 수학 연합 (EU)입니다 \ (2000 \) 또한, --- 세계 수학 년도"유명한 수학자 씨 후아의 생일과 일치 \ (90 \) 기념일. 씨 후아의 고향 진, 수학 퀴즈는 친구의 장엄한 하나의 활동을 조직 \ (XZ \) 도 참여할 수있는 기회를 가질 수있다. 활동은 모든 선수에게 호스트는이 하나 개의 주제에서 활동에 참여합니다 :

길이 가지고 \ (N \) 숫자의 문자열을, 플레이어의 사용이 필요합니다 \ (K \) 로 곱셈을 일 \을 (K + 1 \) 부품, 그래서하는 점을 찾을 \ (K를 +1 \) 제품의 일부가 최대화 될 수있다.

다음과 같이 한편, 플레이어가 제대로 질문의 의미를 이해할 수있을 수 있도록하기 위해, 운영자는 예를 인용 :

디지트 스트링 : (\ 312 \)\ (N = 3 \.) , \ (K = 1 \.) 두 시점 시스템이있다 :

(\. \ 3 = 12 \ 시간 36) , \ (31 \ 2 = 62 시간 \이다) 이 경우, 그 결과는 환자의 요구 사항에 일치한다 \ (31 인 \ 2 = 62 배 \)

지금, 당신은 당신의 친구를 도와 \ (XZ \) 정답을 얻을 수있는 프로그램을 설계합니다.

\ (\ 컬러 {빨간색} {\ mathcal {입력 \ 형식}} \)

입력 된 프로그램의 두 행 : 첫 번째 줄 22 자연수 갖는다 \ (N, K \) , 두 번째 행은 길이이다 \ (N \) 숫자 문자열.

\ (\ 컬러 {빨간색} {\ mathcal {출력 \ 형식}} \)

그 결과, 입력의 최대 제품에 대하여, 화면에 표시되고, 출력 (자연수)을 수득한다.

\ (\ 컬러 {빨간색} {\ mathcal {DataSize \ 계약}} \)

\ (6≤N≤40,1≤K≤6 \)

\ (\ 컬러 {빨간색} {\ mathcal {해결}} \)

선형 DP

주문 \ (DP [I] [j는 ] \) 이전 나타내는 \ (I는 \) 문자 삽입 \ (J \) 의 열거 얻을 수있는 최대의 곱 번째를 \ (J \) 삽입 승산 토륨 위치 ( \ (K \) 숫자 후)는 전사 식을 얻을 수있다 :

\ [DP [I] [J] = \ 최대 {(DP) [K] [J-1] * NUM (K + 1, i)는} \ \ \ \ \ \ (나는 당량 N을 \ 2 \ 당량, 1 \ 당량 J \ 당량 \ 분 (I-1, K), J \ 당량 K <I) \]

초기화 \ (DP [I] [0 ] = NUM (1, ⅰ) \ \ \ (1 \ 당량 제가 당량의 N를 \) \)

\ (\ 컬러 {빨간색} {\ mathcal {코드}} \)

#include <bits/stdc++.h>
#define LL long long
#define reg register

using namespace std;

const int kN = 100;

LL dp[kN][kN];
string num;
int N, K; 

LL Cut(int l, int r) {
  LL ret = 0;
  for (reg int i = l; i <= r; ++i)
    ret = ret * 10 + num[i - 1] - '0';
  return ret;
}

int main() {
  scanf("%d%d", &N, &K);
  cin >> num;
  for (reg int i = 1; i <= N; ++i)
    dp[i][0] = dp[i - 1][0] * 10 + num[i - 1] - '0';
  for (reg int i = 2; i <= N; ++i)
    for (reg int j = 1; j <= min(i - 1, K); ++j)
      for (reg int k = j; k < i; ++k)
        dp[i][j] = max(dp[i][j], dp[k][j - 1] * Cut(k + 1, i));
  printf("%lld\n", dp[N][K]);
  return 0;
}

추천

출처www.cnblogs.com/1miharu/p/11329459.html