Algorithm 拍摄气球并获得最高分数

Algorithm 拍摄气球并获得最高分数,algorithm,recursion,dynamic-programming,Algorithm,Recursion,Dynamic Programming,共有10个气球,每个气球上都有一些点。如果客户拍摄气球,他将获得与左侧气球上的点乘以右侧气球上的点相等的点。客户必须获得最高积分才能赢得这场比赛。最高分数是多少?他应该按什么顺序射出气球来获得最高分数 请注意,如果只有一个引出序号,则返回该引出序号上的点 我正在检查所有10个!排列以找出最大点。有没有其他有效的方法来解决这个问题?正如我在评论中所说的,有位掩码的动态规划解决方案是可能的,我们可以做的是保留一个位掩码,其中1在位索引在i意味着第i个气球被射杀,一个0表示它没有被射杀 因此,只需要一

共有10个气球,每个气球上都有一些点。如果客户拍摄气球,他将获得与左侧气球上的点乘以右侧气球上的点相等的点。客户必须获得最高积分才能赢得这场比赛。最高分数是多少?他应该按什么顺序射出气球来获得最高分数

请注意,如果只有一个引出序号,则返回该引出序号上的点


我正在检查所有10个!排列以找出最大点。有没有其他有效的方法来解决这个问题?

正如我在评论中所说的,有位掩码的动态规划解决方案是可能的,我们可以做的是保留一个位掩码,其中
1
索引在
i
意味着
第i个
气球被射杀,一个
0
表示它没有被射杀

因此,只需要一个掩码的动态规划状态,在每个状态下,我们可以通过迭代所有未被射出的气球,并尝试射出它们来找到最大值,从而过渡到下一个状态

这种解决方案的时间复杂度为:
O((2^n)*n*n)
,空间复杂度为
O(2^n)

C++中的代码,未调试,可能需要调试:

int n = 10, val[10], dp[1024];    //set all the values of dp table to -1 initially

int solve(int mask){
    if(__builtin_popcount(mask) == n){
        return 0;
    }
    if(dp[mask] != -1) return dp[mask];

    int prev = 1, ans = 0;
    for(int i = 0;i < n;i++){
        if(((mask >> i) & 1) == 0){ //bit is not set
            //try to shoot current baloon
            int newMask = mask | (1 << i);
            int fwd = 1;
            for(int j = i+1;j < n;j++){
                if(((mask >> j) & 1) == 0){
                    fwd = val[j];
                    break;
                }
            }
            ans = max(ans, solve(newMask) + (prev * fwd));
            prev = val[i];
        }
    }
    return dp[mask] = ans;
}
int n=10,val[10],dp[1024]//最初将dp表的所有值设置为-1
整数解算(整数掩码){
如果(uuu内置_uuPopCount(掩码)==n){
返回0;
}
如果(dp[mask]!=-1)返回dp[mask];
int prev=1,ans=0;
对于(int i=0;i>i)&1)==0){//未设置位
//试着射击当前的气球
int newMask=mask |(1>j)&1=0){
fwd=val[j];
打破
}
}
ans=最大值(ans,求解(新掩码)+(上一个*fwd));
prev=val[i];
}
}
返回dp[mask]=ans;
}
#包括
使用名称空间std;
int findleft(int arr[],int n,int j,bool isBurst[],bool&found)
{
如果(j=0;i--)
{
如果(!isBurst[i])
{
返回arr[i];
}
}
发现=错误;
返回1;
}
int findright(int arr[],int n,int j,bool isBurst[],bool&found)
{
如果(j>=n)
{
发现=错误;
返回1;
}
对于(int i=j+1;i)
{
ans=电流;
返回;
}
}
对于(int i=0;i>n;
int ans=0;
int-arr[n];
bool-isBurst[n];
对于(int i=0;i>arr[i];
isBurst[i]=假;
}
最大点(arr,n,0,0,ans,0,isBurst);

如果他射出最左边或最右边的气球怎么办?0分?如果他射出最左边或最右边的气球,那么1分将向左或向右乘以1分。我认为这可以通过使用带位掩码的动态规划来解决。直觉上,总是下一个(左或右)射出气球似乎很好到得分最多的一个。不确定这是否总是导致最佳解决方案。在某些情况下,它会失败。在2位掩码测试中,请将
&&
更改为
&
。否则对我来说很好:)用于N Baloon的Java解决方案