2 solutions

  • 0
    @ 2025-8-22 9:32:43
    #include<bits/stdc++.h>
    using namespace std;
    const int N=300000;
    int f[N][2];
    int main()
    {
    	int m,s,t;
    	cin>>m>>s>>t;
    	for(int i=1;i<=t;i++)
    	{
    		if(m>=10)
    		{
    			f[i][0]=f[i-1][0]+60;
    			m-=10;
    		}
    		else
    		{
    			f[i][0]=f[i-1][0];
    			m+=4;
    		}
    		f[i][1]=f[i][0];
    		f[i][1]=max(f[i][1],f[i-1][1]+17);
    	}
    	for(int i=1;i<=t;i++)
    	{
    		if(max(f[i][0],f[i][1])>=s)
    		{
    			cout<<"Yes"<<endl;
    			cout<<i;
    			return 0;
    		}
    	}
    	cout<<"No"<<endl;
    	cout<<max(f[t][0],f[t][1]);
    	return 0;
    }
    
    
    • 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
      7
      Tags
      # Submissions
      22
      Accepted
      9
      Uploaded By