UVA 10118 Free Candies

传送门

题意翻译

桌上有4堆糖果,每堆有N(N≤40)颗。佳佳有一个最多可以装5颗糖的小篮子。他每次 选择一堆糖果,把最顶上的一颗拿到篮子里。如果篮子里有两颗颜色相同的糖果,佳佳就把 它们从篮子里拿出来放到自己的口袋里。如果篮子满了而里面又没有相同颜色的糖果,游戏 结束,口袋里的糖果就归他了。当然,如果佳佳足够聪明,他有可能把堆里的所有糖果都拿 走。为了拿到尽量多的糖果,佳佳该怎么做呢?

来自:刘汝佳《算法竞赛入门经典》

题目描述

PDF

输入输出格式

输入格式:

输出格式:

输入输出样例

输入样例#1: 复制
5
1 2 3 4
1 5 6 7
2 3 3 3
4 9 8 6
8 7 2 1
1
1 2 3 4
3
1 2 3 4
5 6 7 8
1 2 3 4
0
输出样例#1: 复制
8
0
3

 

#1:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define maxn 41
using namespace std;
int candy[5],n,l[5],dp[maxn][maxn][maxn][maxn],f[5][maxn],num;
int dfs(int Q,int num)
{    
    int a,b,c,d;
    if(l[1]==n||l[2]==n||l[3]==n||l[4]==n||num==5) 
    if(dp[l[1]][l[2]][l[3]][l[4]])
    return dp[l[1]][l[2]][l[3]][l[4]];
    for(int i=1;i<=4;i++)
    {
        if(l[i]<n) 
        {
        int j=1<<f[i][l[i]];
        l[i]++;
        if(Q&j)dp[l[1]][l[2]][l[3]][l[4]]=max(dp[l[1]][l[2]][l[3]][l[4]],dfs(Q-j,num-1)+1);
        else dp[l[1]][l[2]][l[3]][l[4]]=max(dp[l[1]][l[2]][l[3]][l[4]],dfs(Q+j,num+1)); 
        l[i]--;
        }
    } 
     return dp[l[1]][l[2]][l[3]][l[4]];
} 
int main()
{
    while(cin>>n&&n!=0)
    {
        memset(dp,0,sizeof dp);
        memset(l,0,sizeof l);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            cin>>f[j][i];
        cout<<dfs(0,0)<<endl;
    }
}

#2:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define maxn 41
using namespace std;
int candy[5],n,l[5],dp[maxn][maxn][maxn][maxn],f[5][maxn],num;
int dfs(int Q,int num)
{    
    int a,b,c,d;
    if(l[1]==n||l[2]==n||l[3]==n||l[4]==n||num==5) return 0;
    if(dp[l[1]][l[2]][l[3]][l[4]])
    return dp[l[1]][l[2]][l[3]][l[4]];
    for(int i=1;i<=4;i++)
    {
        if(l[i]<n) 
        {
        int j=1<<f[i][l[i]];
        l[i]++;
        if(Q&j)dp[l[1]][l[2]][l[3]][l[4]]=max(dp[l[1]][l[2]][l[3]][l[4]],dfs(Q-j,num-1)+1);
        else dp[l[1]][l[2]][l[3]][l[4]]=max(dp[l[1]][l[2]][l[3]][l[4]],dfs(Q+j,num+1)); 
        l[i]--;
        }
    } 
     return dp[l[1]][l[2]][l[3]][l[4]];
} 
int main()
{
    while(cin>>n)
    {
        if(n==0)break;
        memset(dp,0,sizeof dp);
        memset(l,0,sizeof l);
        for(int i=0;i<4;i++)
            for(int j=0;j<n;j++)
            cin>>f[i][j];
        cout<<dfs(0,0)<<endl;
    }
}

#3:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define maxn 41
using namespace std;
int n,l[5],dp[maxn][maxn][maxn][maxn],f[5][maxn];
int dfs(int Q,int num)
{    
    if(l[1]==n&&l[2]==n&&l[3]==n&&l[4]==n&&num==5) return dp[l[1]][l[2]][l[3]][l[4]]=0;
    if(dp[l[1]][l[2]][l[3]][l[4]])
    return dp[l[1]][l[2]][l[3]][l[4]];
    for(int i=0;i<4;i++)
    {
        if(l[i]<n) 
        {
        int j=1<<f[i][l[i]];
        l[i]++;
        if(Q&j)dp[l[1]][l[2]][l[3]][l[4]]=max(dp[l[1]][l[2]][l[3]][l[4]],dfs(Q-j,num-1)+1);
        else if(num<5)dp[l[1]][l[2]][l[3]][l[4]]=max(dp[l[1]][l[2]][l[3]][l[4]],dfs(Q+j,num+1)); 
        l[i]--;
        }
    } 
     return dp[l[1]][l[2]][l[3]][l[4]];
} 
int main()
{
    while(cin>>n)
    {
        if(n==0)break;
        memset(dp,0,sizeof dp);
        memset(l,0,sizeof l);
        for(int i=0;i<4;i++)
            for(int j=0;j<n;j++)
            cin>>f[i][j];
        cout<<dfs(0,0)<<endl;
    }
}

#4:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define maxn 41
using namespace std;
int n,l[5],dp[maxn][maxn][maxn][maxn],f[maxn][5];
int dfs(int Q,int num)
{    
    if(dp[l[0]][l[1]][l[2]][l[3]]!=-1)
    return dp[l[0]][l[1]][l[2]][l[3]];        
    if((l[0]==n&&l[1]==n&&l[2]==n&&l[3]==n)||num==5) return dp[l[0]][l[1]][l[2]][l[3]]=0;
    for(int i=0;i<4;i++)    
    {
        if(l[i]<n) 
        {
        int j=1<<f[l[i]][i];
        l[i]++;
        if(j&Q)dp[l[0]][l[1]][l[2]][l[3]]=max(dp[l[0]][l[1]][l[2]][l[3]],dfs(Q-j,num-1)+1);
        else if(num<5)dp[l[0]][l[1]][l[2]][l[3]]=max(dp[l[0]][l[1]][l[2]][l[3]],dfs(Q+j,num+1)); 
        l[i]--;
        }
    } 
     return dp[l[0]][l[1]][l[2]][l[3]];
} 
int main()
{
    while(cin>>n)
    {
        if(n==0)break;
        memset(dp,-1,sizeof dp);
        memset(l,0,sizeof l);
        for(int i=0;i<n;i++)
            for(int j=0;j<4;j++)
            cin>>f[i][j];
        cout<<dfs(0,0)<<endl;
    }
}

 #5:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define maxn 41
using namespace std;
int n,l[5],dp[maxn][maxn][maxn][maxn],f[maxn][5];
int dfs(int Q,int num)
{    
    if(dp[l[0]][l[1]][l[2]][l[3]]!=-1)
    return dp[l[0]][l[1]][l[2]][l[3]];        
    if((l[0]==n&&l[1]==n&&l[2]==n&&l[3]==n)||num==5) return dp[l[0]][l[1]][l[2]][l[3]]=0;
    for(int i=0;i<4;i++)    
    {
        if(l[i]<n)
        {
        int j=1<<f[l[i]][i];
        l[i]++;
        if(j&Q)dp[l[0]][l[1]][l[2]][l[3]]=max(dp[l[0]][l[1]][l[2]][l[3]],dfs(Q-j,num-1)+1);
        else if(num<5)dp[l[0]][l[1]][l[2]][l[3]]=max(dp[l[0]][l[1]][l[2]][l[3]],dfs(Q+j,num+1));
        l[i]--;
        }
    }
     return dp[l[0]][l[1]][l[2]][l[3]];
}
int main()
{
    while(cin>>n)
    {
        if(n==0)break;
        memset(dp,-1,sizeof dp);
        memset(l,0,sizeof l);
        for(int i=0;i<n;i++)
            for(int j=0;j<4;j++)
            cin>>f[i][j];
        cout<<dfs(0,0)<<endl;
    }
}

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define maxn 41
using namespace std;
int n,l[5],dp[maxn][maxn][maxn][maxn],f[maxn][5];
int dfs(int Q,int num)
{   
    int &now=dp[l[0]][l[1]][l[2]][l[3]];
    if(now!=-1)
    return now;      
    if((l[0]==n&&l[1]==n&&l[2]==n&&l[3]==n)||num==5) return now=0;
    for(int i=0;i<4;i++)    
    {
        if(l[i]<n)
        {
        int j=1<<f[l[i]][i];
        l[i]++;
        if(j&Q)now=max(now,dfs(Q-j,num-1)+1);
        else if(num<5)now=max(now,dfs(Q+j,num+1));
        l[i]--;
        }
    }
     return now;
}
int main()
{
    while(1)
    {
        cin>>n;
        if(n==0)break;
        memset(dp,-1,sizeof dp);
        memset(l,0,sizeof l);
        for(int i=0;i<n;i++)
            for(int j=0;j<4;j++)
            cin>>f[i][j];
        cout<<dfs(0,0)<<endl;
    }
}

 很好奇为什么#5和AC代码就是换了个名字答案却不一样。

转载于:https://www.cnblogs.com/JCRL/p/10109814.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段程序的目的是计算将糖果均分给两个人所需的最小操作次数。让我们来分析一下为什么输入47会得到7作为结果。 当输入为47时,程序通过递归调用 `divide(candies, count, minCount)` 进行计算。初始调用是 `divide(47, 0, minCount)`。 首先,程序检查是否只剩下一个糖果。由于47不等于1,所以不满足条件。 接下来,程序检查47是否为偶数。由于47不是偶数,所以执行 `else` 分支。 在 `else` 分支中,程序进行了两个递归调用: 1. `divide(candies + 1, count + 1, minCount)`:这是将糖果数量加1的操作,并将操作次数加1。 2. `divide(candies - 1, count + 1, minCount)`:这是将糖果数量减1的操作,并将操作次数加1。 这两个递归调用会产生分支,并继续递归地进行计算。 对于第一个递归调用 `divide(candies + 1, count + 1, minCount)`,它会将糖果数量从47增加到48,并将操作次数从0增加到1。 接着,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为48。由于48是偶数,程序执行 `divide(candies // 2, count + 1, minCount)`,将糖果数量除以2,并将操作次数加1。 然后,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为24。同样地,程序将糖果数量除以2,并将操作次数加1。 接下来,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为12。同样地,程序将糖果数量除以2,并将操作次数加1。 继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为6。同样地,程序将糖果数量除以2,并将操作次数加1。 接下来,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为3。由于3是奇数,程序将糖果数量加1,并将操作次数加1。 然后,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为4。同样地,程序将糖果数量除以2,并将操作次数加1。 最后,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为2。同样地,程序将糖果数量除以2,并将操作次数加1。 此时,糖果数量变为1,满足终止条件。程序将当前的操作次数1与 `minCount[0]` 中的值进行比较,并将较小值更新到 `minCount[0]` 中。 综上所述,最小操作次数为7。因此,输入47得到的结果是7。 如果你有任何其他问题,请告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值