【问题标题】:How do I solve this dynamic-programming problem(winning strategy)?我该如何解决这个动态规划问题(获胜策略)?
【发布时间】:2019-10-07 10:07:01
【问题描述】:

我遇到了这个 dp 问题。如下:-

艾莉亚史塔克和珊莎史塔克是姐妹,但经常因为一个或另一个原因互相打架。最近,珊莎在狩猎游戏中作弊打败了艾莉亚,并取笑她。艾莉亚充满愤怒,想要报仇。艾莉亚召唤她的姐姐珊莎参加战斗,珊莎接受了。

战斗由 R 轮组成,每轮将测试不同的技能。该技能可能是射箭,剑术或其他任何东西。每轮结束后,该轮的获胜者将获得一分。完成所有 R 轮比赛后,得分最高的一方为总冠军。

Arya 很生气,不仅想赢得战斗,还想以这样的方式击败 Sansa,在每一轮之后,她的分数至少是 Sansa 的 P 倍。她正忙于准备战斗,并听说过你的技能。她希望你找出在提供的条件下她可以用多少种方法打败珊莎并报仇。

获胜的顺序区分不同的方式。 示例:让我们考虑一下,有 3 轮。

案例一:艾莉亚第一轮赢,珊莎第二轮,艾莉亚第三轮

顺序:- 艾莉亚,珊莎,艾莉亚

案例2:艾莉亚赢了第一轮,艾莉亚也赢了第二轮,珊莎赢了第三轮

顺序:-Arya,Arya,Sansa

上述两种情况彼此不同,被认为是两种不同的方式。

注意:因为答案可能很大,所以取模 10^9 + 7。

输入格式: 输入的第一行包含测试用例的数量,T 每个测试用例的唯一一行由两个空格分隔的整数 R 和 P 组成。

约束: 1

1

1

输出格式:-

对于每个测试用例,在单独的一行中打印出可能的方法数。

示例测试用例 1

输入

2 4 2 2 2

输出

3

1

解释 测试用例 1:

在给定条件下,Arya 可以通过三种方式获胜

方式 1:前三轮由 Arya 获胜,最后一轮由 Sansa 获胜

艾莉亚, 艾莉亚, 艾莉亚, 珊莎

方式 2:前两轮比赛由 Arya 获胜。第三轮由珊莎获胜,最后一轮由艾莉亚获胜。

艾莉亚, 艾莉亚, 珊莎, 艾莉亚

方式 3:Arya 赢得所有四轮比赛。

艾莉亚, 艾莉亚, 艾莉亚, 艾莉亚

测试用例 2:在这种情况下只有一种获胜方式,即 Arya 赢得两轮比赛。

艾莉亚, 艾莉亚

我的问题代码:-

enter code gghere
#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
ll e=1000000007;
ll a2[2000][2000];
int main() 
{ll t;
cin>>t;
ll t1=t;
while(t--)
{

ll r,p;

cin>>r>>p;


//map<pair<ll,ll>,ll> a2;
//a2[{1,0}]=1;


a2[1][0]=1;
ll w[20000][9];
ll op=0;
w[op][0]=1;
w[op][1]=0;
w[op][2]=1;
op++;

ll i1=0;
ll i=2;
while(i<=r)
{



ll b[20000][7];
ll pass=0;
i1=0;
while(i1<op)
{

ll c1,c2;
ll c3;
c1=w[i1][0]%e;
c2=w[i1][1]%e;
c3=w[i1][2]%e;



if((c1+1)>=p*c2)
{
 //....(c1+1,c2)+=c3
 b[pass][0]=c1+1;
 b[pass][1]=c2;
 b[pass][2]=c3%e;

 pass++;
}
if(c1>=p*(c2+1))
{   
 b[pass][0]=c1;
 b[pass][1]=c2+1;
 b[pass][2]=c3%e;
 //.......(c1,c2+1)+=c3
 pass++;
}

i1++;  
}

i1=0;
while(i1<op)
{
ll x1=w[i1][0];
ll x2=w[i1][1];
a2[x1][x2]=0;
w[i1][0]=0;
w[i1][1]=0;
w[i1][2]=0%e;


i1++;
}

op=0;
ll j=0;
while(j<pass)
{


    ll x1=b[j][0];
    ll x2=b[j][1];
    ll x3=b[j][2]%e;

    if(a2[x1][x2]==0)
    {

        w[op][0]=x1;

        w[op][1]=x2;

        op++;
    }
    else
    {


    }


    a2[x1][x2]=(a2[x1][x2]%e+x3%e)%e;




    j++;
}

i1=0;
while(i1<op)
{
    ll m1=w[i1][0];
    ll m2=w[i1][1];

    w[i1][2]=a2[m1][m2]%e;



    i1++;
}









i++;
}

i1=0;
ll c4=0;
while(i1<op)
{

ll c1,c2;
ll c3;
c1=w[i1][0]%e;
c2=w[i1][1]%e;

//cout<<c1<<" "<<c2;

//cout<<"\n";


c3=w[i1][2]%e;
c4=(c4%e+c3%e)%e;
//cout<<c1<<" "<<c2<<" "<<c3<<"\n";
c4=c4%e;
i1++;  
}
cout<<c4;

cout<<"\n";




ll o=0;
while(o<=1500)
{

ll p=0;
while(p<=1200)
{

a2[o][p]=0;

p++;
}



o++;
}







}



return 0;    
}

我想确认我的方法是否正确,如果是,那我需要改变什么?我可以做得更好吗?

谢谢:-)

【问题讨论】:

  • 代码不可读,格式不正确,也没有解释为什么它可以工作。如果它是对的,那将是多么幸福的巧合。
  • 我确实试图以一种有用的方式来表达它。如果您养成了格式化代码并编写代码以使其更具可读性的习惯,那么它正确工作的机会将大大增加。如果不出意外,其他人将能够真正阅读并提供一些帮助。

标签: arrays dynamic-programming


【解决方案1】:

不明白你的方法。您可以将此问题转换为以下等式:

f(currentMatch,aryaWon) = f(currentMatch+1,aryaWon+1) + f(currentMatch+1,aryaWon)

从你可以推导出的状态,

sansaWon = currentMatch - aryaWon

基本情况是,

if(aryaWon &lt; p * sansaWon ) return 0 和

if(currentMatch == r) return 1

下面是实现:

#define mxn 1003
#define mod 1000000007
int p,r;
int dp[mxn][mxn];

int f(int match,int arya) {
        int sansa = match - arya;

        if(arya < p * sansa) return 0;

        if(match == r) return 1;

        if(dp[match][arya] != -1)
                return dp[match][arya];

        int ans = f(match+1,arya + 1) + f(match+1,arya);
        ans %= mod;

        return dp[match][arya] = ans;
}

int main()
{
        int t;
        cin >> t;
        while(t--) {
                cin >> r >> p;
                memset(dp,-1,sizeof dp);
                cout << f(0,0) << endl;
        }
        return 0;
}

时间和空间复杂度为O(r^2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    相关资源
    最近更新 更多