codeforces 82D Two out of Three

1801 단어
제목:
한 팀을 주면 각자 처리 시간이 있다. 매번 팀 전 세 사람 중 두 사람을 선택하여 처리할 수 있다. 처리 시간은 이 두 사람의 시간의 최대치와 같다.처리 시간의 최소치를 묻는다.
문제 풀이:
이런 제목은 약간 배열 조합과 같고 각 피드의 상황도 서로 다른 하위 상황에 대응하기 때문에 검색으로 하면 되겠지만 시간이 초과될 수 있기 때문에 dp로 기억하면 기억이 폭발한다.
dp[i][j]는 i, j를 머리로 하는 대열의 최소 시간을 나타낸다.
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<map>
using namespace std;
typedef long long lld;
const int oo=0x3f3f3f3f;
const lld OO=1LL<<61;
const int MOD=1000000007;
int dp[1005][1005];
int a[1005];
int n;

int dfs(int i,int j)
{
    if(dp[i][j]!=-1)return dp[i][j];
    if(j>n)return dp[i][j]=a[i];
    if(j==n)return dp[i][j]=max(a[i],a[j]);
    dp[i][j]=max(a[i],a[j])+dfs(j+1,j+2);
    dp[i][j]=min(dp[i][j],max(a[i],a[j+1])+dfs(j,j+2));
    dp[i][j]=min(dp[i][j],max(a[j],a[j+1])+dfs(i,j+2));
    return dp[i][j];
}

void output(int i,int j)
{
    if(j>n)
    {
        printf("%d
",i); } else if(j==n) { printf("%d %d
",i,j); } else if(dp[i][j]==max(a[i],a[j])+dp[j+1][j+2]) { printf("%d %d
",i,j); output(j+1,j+2); } else if(dp[i][j]==max(a[i],a[j+1])+dp[j][j+2]) { printf("%d %d
",i,j+1); output(j,j+2); } else if(dp[i][j]==max(a[j],a[j+1])+dp[i][j+2]) { printf("%d %d
",j,j+1); output(i,j+2); } } int main() { while(scanf("%d",&n)!=EOF) { memset(dp,-1,sizeof dp); for(int i=1;i<=n;i++) scanf("%d",&a[i]); printf("%d
",dfs(1,2)); output(1,2); } return 0; } /** 4 1 2 3 4 5 2 4 3 1 4 */

좋은 웹페이지 즐겨찾기