神奇思路求证明错误
  • 板块P1484 种树
  • 楼主cengzh
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/11/25 15:03
  • 上次更新2024/11/25 19:01:14
查看原帖
神奇思路求证明错误
640816
cengzh楼主2024/11/25 15:03

乱写...想出这么一个神奇做法:

假设k无限大,那么这是一个很简单的dp题

在这个dp中我们是可以得到这个最优的树坑的情况的

那么答案只可能出现在这些树坑中(?

因此如果树坑的数量 < k,那么我们只需选取前k个获利最大的树坑求和即为答案了。

但是只得30pts,有可能是码力不足,也有可能是思路错了。求证明QwQ

# include <stdio.h>
# include <iostream>
# include <bits/stdc++.h>

using namespace std;

int v[300005];
int dp[300005][2];

bool cmp(int x,int y)
{
  return v[x] > v[y];
}

int main (void)
{
  int n,k;
  scanf ("%d %d",&n,&k);

  for (int i=1;i<=n;i++)
  {
    scanf ("%d",&v[i]);
  }

  dp[1][0] = 0;
  dp[1][1] = v[1];

  for (int i=2;i<=n;i++)//dp过程
  {
    dp[i][0] = max(dp[i-1][1],dp[i-1][0]);
    dp[i][1] = v[i] + dp[i-1][0];
  }

  int ans_p[300005];
  int len=0;
  
  //求树根位置
  for (int i=n;i>=1;)
  {
    if (dp[i][1] > dp[i][0])
    {
      ans_p[len++] = i;
      i -= 2;
    }
    else
    {
      i--;
    }
  }
  //统计答案
  if (len > k)
  {
    sort(ans_p,ans_p+len,cmp);
    int ans=0;
    for (int i=0;i<k;i++)
    {
      ans += v[ans_p[i]];
    }
    printf ("\n%d",ans);
  }
  else
  {
    printf ("%d",max(dp[n][0],dp[n][1]));
  }

  return 0;
}

2024/11/25 15:03
加载中...