360笔试遇到的博弈问题(DP)

昨天,第一次参加找工作的笔试,最后一道编程题,总觉得很熟悉,但是没有做出来。以后,有时间记录下遇到的问题,便于以后看看。
题目是360公司的,大概讲的是两队海盗分金子,每次只能从一端取(左或者右),假设每队都按照最优的策略,问最后各取多少金子。
以前在LeetCode里也碰到过类似做游戏的问题,464. can I win,486. Predict the Winner。事后,发现这个题目和486几乎一样,只不过,486是判断能不能赢,这里返回的是各个结果。


说明:这里应该用备忘录的DP解法,这里的核心是当对于nums[s,…,e],如果选择了nums[s],那么对法一定想办法在nums[s+1,…,e]中取能得到最大值的解法。总共有nums[s,…,e]的sum的金子,除去对方的DP(s+1,e)个金子,剩下的就是自己的。同样,选择nums[e]的话,也会有一个结果。因为双方都想最优化,所以取较大值即可。

#include 
#include 
using namespace std; 
int DP(vector<vector<int> > &dp, int s, int e,vector<int>& nums,vector<int> &sum)
{
    if(s==e) return nums[s];
    if(dp[s][e]!=0) return dp[s][e];
    int tmp=max(nums[s]-DP(dp,s+1,e,nums,sum)+sum[e+1]-sum[s+1],nums[e]-DP(dp,s,e-1,nums,sum)+sum[e]-sum[s]);
    dp[s][e]=tmp;
    return dp[s][e];
} 


int main(){
/*  int T;cin>>T;
    for(int i=0;i>n;
        vector nums(n);
        for(int i=0;i>nums[i];
        vector sums(n,0);
        sums[0]=nums[0];
        for(int i=1;i > dp(n,vector(n,0));
        int r=DP(dp,0,n-1,nums,sums);
        cout<
    int n=6;
    int a[6]={4,7,2,9,5,2};
    vector<int> nums(n);
        for(int i=0;ivector<int> sums(n+1,0);
        sums[0]=0;
        for(int i=1;i<=n;i++) 
        {
          sums[i]=sums[i-1]+nums[i-1];
          cout<vector<vector<int> > dp(n,vector<int>(n,0));
        int r=DP(dp,0,n-1,nums,sums);
        cout<" "<

可以在赛马网找打原题的应该。
对于,DP果然很重要,/(ㄒoㄒ)/~~

你可能感兴趣的:(动态规划)