1 solutions

  • 0
    @ 2024-6-5 14:07:16

    模拟(OTOT)

    使用两个人,一个人只能走(但是可以瞬移到第二个人的位置),另一个人只能使用魔法,也就是当我们第二个更远的时候,第一个人就会瞬间移动到第二个人的位置。

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int s1=0,s2=0;//s1表示走路和闪现的最大距离,s2表示魔法的距离
        int m,s,t;
        cin>>m>>s>>t;
        for(int i=1;i<=t;i++)
        {
            s1+=17;
            if(m>=10) //使用魔法
            {
                m-=10;
                s2+=60;
            }
            else //回蓝
            {
                m+=4;
            }
            if(s2>s1) //使用魔法更优
            {
                s1=s2;
            }
            if(s1>=s)
            {
                cout<<"Yes"<<endl;
                cout<<i<<endl;
                return 0;
            }
        }
        cout<<"No"<<endl;
        cout<<s1<<endl;
        return 0;
    }
    

    动态规划OTOT

    首先比较跑步和放技能哪个更快:

    跑步:平均一秒 17 放技能:平均2.5秒恢复10点魔法,再加一秒闪烁时间,一共是3.5秒可以移动60米, 所以平均每秒 1717 17 \frac 1 7米 所以放技能稍快一些。

    因此当我们有充足的放技能时间时,一定要放技能,所以只有最后一小段没时间放技能的时候,才会用跑步的方式。

    然后考虑如何求解:

    f[i]f[i]表示用ii的时间,最多可以跑多远。

    先求出只用闪烁技能时,每秒最多可以跑多远。

    再用跑步的方式来“插缝”,递推出结合两种方式时,每秒最多可以跑多远。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=300010;
    int f[N];
    int main()
    {
    	int m,s,t;
    	cin>>m>>s>>t;
    	for(int i=1;i<=t;i++)
    	{
    		if(m>=10) //可以使用魔法 
    		{
    			f[i]=f[i-1]+60;
    			m-=10;
    		}
    		else //休息 
    		{
    			f[i]=f[i-1];
    			m+=4;
    		}
    	}
    	for(int i=1;i<=t;i++) //魔法+跑步 
    	{
    		f[i]=max(f[i],f[i-1]+17);
    	}
    	for(int i=1;i<=t;i++) //枚举每个时间 
    	{
    		if(f[i]>=s)
    		{
    			cout<<"Yes"<<endl;
    			cout<<i;
    			return 0;
    		}
    	}
    	cout<<"No"<<endl; //走不到后面 
    	cout<<f[t]<<endl;
    	return 0;
    }
    
    • 1

    Information

    ID
    419
    Time
    1000ms
    Memory
    128MiB
    Difficulty
    10
    Tags
    # Submissions
    8
    Accepted
    4
    Uploaded By