uva 10118(DP)

1891 단어 dp
UVA 10118
제목:
사탕 네 무더기가 있는데 한 무더기에 n(최대 40개), 바구니 하나, 최대 5개가 들어있다. 우리는 매번 한 무더기의 사탕에서 사탕 하나를 꺼낼 수 밖에 없다.
바구니에 같은 사탕이 두 개 있다면 두 개(한 쌍)의 사탕을 주머니에 넣고 최대 몇 쌍의 사탕을 가져갈 수 있는지 물어볼 수 있다.사탕의 종류는 최대 20종이다. 
사고방식: 기억화 검색
Orz: 입력할 때 실수로 잘못 써서 계속 디버깅을 합니다.자신의 함수에 문제가 없다는 것을 느끼고 오랫동안 고민했다.
문제를 찾아냈을 때 순간적으로.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;
const int maxn = 50;
int num[5];
int tmap[maxn][maxn];
int dp[maxn][maxn][maxn][maxn];
bool vis[25];
int n;
int fin(int all)
{
    if(dp[num[1]][num[2]][num[3]][num[4]] != -1)
        return dp[num[1]][num[2]][num[3]][num[4]];
    if(all == 5)
        return dp[num[1]][num[2]][num[3]][num[4]] = 0;


    int ans = 0;
    for(int i= 1; i <= 4; i++)
    {
        if(num[i]> n)
            continue;


        if(vis[tmap[i][num[i]]])               //          
        {
            vis[tmap[i][num[i]]] = false;
            num[i]+=1;
            ans = max(fin(all-1) + 1,ans);
            num[i]-=1;
            vis[tmap[i][num[i]]] = true;
        }
        else
        {
            vis[tmap[i][num[i]]] = true;
            num[i]+=1;
            ans = max(fin(all+1),ans);
            num[i]-=1;
            vis[tmap[i][num[i]]] = false;

        }

    }
    return dp[num[1]][num[2]][num[3]][num[4]] =ans;
}

int main()
{
    while(scanf("%d",&n) && n)
    {
        for(int j = 1; j <= n; j++)
            for(int i = 1; i <=4; i++)
                scanf("%d",&tmap[i][j]);
        num[1] = num[2] = num[3] = num[4] = 1;
        memset(dp,-1,sizeof(dp));
        memset(vis,false,sizeof(vis));
        printf("%d
",fin(0)); } return 0; }

좋은 웹페이지 즐겨찾기