UVA - 10118 Free Candies

问题

问题是给四个糖果堆(高度为n,n<=40),每次可以从任意一个堆的顶部取一个糖果放在容量为5的篮子中,若篮子中有两个颜色相同,就可以拿走,求最多可以拿走多少个糖果对

分析

状态是dp[a][b][c][d],a,b,c,d分别是从四个堆中拿走的的糖果个数,dp[0][0][0][0]是还没取的时候,可以得到的最多糖果对数量,dp[a][b][c][d]是已经取了a,b,c,d的时候还能够继续拿到的最大糖果数量
本题的思路有点类似于上一题(最长路),不过状态维度稍微多了点,有一点要注意的:不用加入篮子里的糖果数量作为一个维度,而是直接把它计算出来

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=42;
int piles[4][maxn],n,dp[maxn][maxn][maxn][maxn],cnt[21],kase=1;

int DFS(int *num,int bas){
    int &ans=dp[num[0]][num[1]][num[2]][num[3]];
    if(ans>=0) return ans;
    if(bas==5) return ans=0;
    ans=0;
    for(int i=0;i<4;++i){
        if(num[i]==n) continue;
        cnt[piles[i][num[i]]]++;
        int pair=0;
        if((cnt[piles[i][num[i]]] & 1)==0){
            pair=1;
            bas--;
        }else bas++;
        num[i]++;
        ans=max(ans,pair+DFS(num,bas));
        num[i]--;
        if((cnt[piles[i][num[i]]] & 1)==0){
            bas++;
        }else bas--;
        cnt[piles[i][num[i]]]--;
    }
    return ans;
}

int main(void){
    while(cin>>n && n){
        for(int i=0;i<n;++i) {
            for (int j = 0; j < 4; ++j) {
                scanf("%d",&piles[j][i]);
            }
        }

        for(int i=0;i<=n;++i){
            for(int j=0;j<=n;++j)
                for(int l=0;l<=n;++l)
                    for(int m=0;m<=n;++m) dp[i][j][l][m]=-1;
        }
//        memset(dp,-1,sizeof(dp));
        memset(cnt,0,sizeof(cnt));
        int num[4]={0,0,0,0};
        printf("%d\n",DFS(num,0));
        ++kase;
    }
    return 0;
}

UVA - 10118  Free CandiesUVA - 10118  Free Candies carut 发布了15 篇原创文章 · 获赞 0 · 访问量 152 私信 关注
上一篇:Amphiphilic Carbon Molecules UVA - 1606


下一篇:UVA-11526H(n)对称性+几何意义+