首页 > 其他分享 >iwtgm-5

iwtgm-5

时间:2023-11-02 13:34:24浏览次数:28  
标签:int ll 魔法 iwtgm cin ans dp

题目链接

A.

个数为1的数一定会产生贡献,记为x
个数为2的数一定不会产生贡献,直接全部放入集合a
个数>2的数可产生也可不产生贡献,记为y

分类讨论:
x>0:
x为偶数,那么a,b集合平分x,其他全部放入a集合(反正不会有贡献)
x为奇数,需要多一个y放入b,

x<0,全放入a集合
代码:

int cnt[110];
int a[110];
char c[110];
bool f[110];
map<int,char>mp;
void solve()
{
  int n;cin>>n;
  for(int i=1;i<=n;i++){
      cin>>a[i];
      cnt[a[i]]++;
  }
  int fix=0,change_able=0;
  for(int i=1;i<=100;i++){
      if(cnt[i]==1)fix++;
      else if(cnt[i]==2)continue;
      else if(cnt[i]>2)change_able++;
  }
  if(fix%2==0&&fix!=0){
      cout << "YES" << endl;
      int p=1;
      for(int i=1;i<=n;i++){
          if(cnt[a[i]]==1){
              if(p&1)c[i]='A';
              else c[i]='B';
              p++;
          }
      }
      for(int i=1;i<=n;i++){
          if(c[i]=='B')cout<<'B';
          else cout<<'A';
      }
  } else if(fix%2!=0&&fix!=0&&change_able){
      cout << "YES" << endl;
      int p=1;
      for(int i=1;i<=n;i++){
          if(cnt[a[i]]==1){
              if(p&1)c[i]='A';
              else c[i]='B';
              p++;
          }
      }
      for(int i=1;i<=n;i++){
          if(cnt[a[i]]>2){
              c[i]='B';break;
          }
      }
      for(int i=1;i<=n;i++){
          if(c[i]=='B')cout<<'B';
          else cout<<'A';
      }
  } else if(fix==0) {
        cout << "YES" << endl;
        for(int i=1;i<=n;i++)cout<<'A';
    }else cout<<"NO";
}

C.

先考虑如何求最大连续子序列和

int n;
int a[N],dp[N];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    int ans=0;
    for(int i=1;i<=n;i++){
        dp[i]=max(a[i],dp[i-1]+a[i]);//dp[i]表示当前数一定要取(要么自己是头,要么接在上一个后面)
        ans=max(ans,dp[i]);//有可能不要当前数是最优,所以要每次取最大值
    }
    cout<<ans;
}

dp[i][]表示一定要取当前数
现在是加了状态,
3种:
dp[i][0]表示到目前是还没用魔法的,当前数无魔法
dp[i][1]表示到目前正在用魔法,当前数有魔法
dp[i][2]表示魔法已经用完了,当前数无魔法

int n;
ll x;
ll a[N],dp[N][3];
void solve()
{
    cin>>n>>x;
    for(int i=1;i<=n;i++)cin>>a[i];
    ll ans=0;
    for(int i=1;i<=n;i++){
        dp[i][0]=max({a[i],dp[i-1][0]+a[i]});//自己是头或者接到前面
        dp[i][1]=max({dp[i-1][0]+a[i]*x,dp[i-1][1]+a[i]*x,a[i]*x});//前一个数没用魔法或者用魔法加上当前数用魔法,或者自己用魔法当头
        dp[i][2]=max({dp[i-1][1]+a[i],dp[i-1][2]+a[i],a[i]});//前一个数用魔法或用完魔法加上当前数,或者自己当头
        ans=max({ans,dp[i][0],dp[i][1],dp[i][2]});//同样有可能不要当前数更优,每次都要比较
    }
    cout<<ans;
}

更简便的:

int n;
ll x;
ll a[N],dp[N][5];//dp[i][]表示一定要取当前数
void solve()
{
    cin>>n>>x;
    for(int i=1;i<=n;i++)cin>>a[i];
    ll ans=0;
    for(int i=1;i<=n;i++){
        dp[i][0]=max(dp[i-1][0]+a[i],0ll);//因为子序列可以为空,所以当前数是负数的话直接置0更优,和接到前面比较(前面>=0)
        dp[i][1]=max(dp[i][0],dp[i-1][1]+a[i]*x);//此时dp[i][1]和dp[i][0]比较,只有dp[i-1][1]是因为上一次的dp[i][1]和dp[i][0]已经比过了,也就是说此时的dp[i-1][1]中的数是上一次的dp[i][1]和dp[i][0]的较大值
        dp[i][2]=max(dp[i][1],dp[i-1][2]+a[i]);//同上理
        ans=max(ans,dp[i][2]);//同样可能不取当前数会更优,所以每次都要比较
    }
    cout<<ans;
}

标签:int,ll,魔法,iwtgm,cin,ans,dp
From: https://www.cnblogs.com/wwww-/p/17794130.html

相关文章

  • iwtgm-4
    CodeforcesBetaRound73(Div.2Only)B.数据小,暴力一点的方式更好写,自己写的优化一点的出现跑不出来的情况优化是把所有当前字母的位置和S的位置算一个距离,取最小确实预处理出最短距离进行映射会更好intn,m,len,vis[27],ans;doubledis[27],x;charmp[35][35];double......
  • iwtgm-10
    题目链接A.手玩,左右循环后对应位置字符相同,可得到:如果只有两个字符一定可以如果是奇数,那么必须全部相同如果是偶数,那么奇数位置的要全部相同,偶数位置的要全部相同卡的点是相对位置不变,可以删除任意位置,如何判奇数全部相同,偶数全部相同后来看@zys111代码,因为只有两种字符(可......
  • iwtgm-9
    题目链接dp,自己写的时候没有考虑完全状态转移,其实是滑动窗口dp,需要维护一段区间的最小值1-n内的数显然能一步得到,考虑n+1到y,可由前面的状态加数得到也可以乘数得到,考虑加,其实是区间长度为n的滑动窗口的最小值+1考虑乘,若当前数i能整除mi,则dp[mi]+1inta[N],dp[N],q[N],tt=-1,......
  • iwtgm-8
    题目链接A.模拟,先遍历一遍,出现0,则i+x和i-x存在则必是0再遍历一遍,出现1,判i+x和i-x位上若已经是1或还没被赋值则满足题意,否则失败退出输出是当前位是1,则输出1,否则输出0.因为1的限制范围明确,其余都填0voidsolve(){strings;cin>>s;intx;cin>>x;charc[N];......