• 7.4 魔术球问题弱化版


    题目描述

    假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球。

    (1)每次只能在某根柱子的最上面放球。

    (2)在同一根柱子中,任何 2 个相邻球的编号之和为完全平方数。

    试设计一个算法,计算出在 n 根柱子上最多能放多少个球。例如,在 4 根柱子上最多可放 11 个

    对于给定的 n,计算在 n 根柱子上最多能放多少个球。

    输入描述

    第 1 行有 1 个正整数 n,表示柱子数。

    输出描述

    一行表示可以放的最大球数

    4

    样例输出。

    样例输入

    11

    题目限制(为什么说弱化版就在这里)

    N<=60,时限为3s;比起原题还有弱化在不用打出方案,方案太坑了

     

    本题为一个网络流问题的弱化版,结果弱化成模拟了。。。

    所以,就直接按模拟做吧,用了一点小技巧:

    1.贪心,尽可能多地让球都叠加在一个柱子上,毕竟,即使一个数没有能与它组成平方数,他还可以独占一个柱子

    贪心的正确性证明:

    能够证明,按照贪心的思路,每一步得到的都是最优解,首先,只有当出现一个数必须另开一列放的时候,才能会出现最优解的问题。

    如果当前的数a必须单开一列,那么所有能与a组成平方数的数字b,b上面都已经放了数字,如果将a,b调换,那么b将无处可去,也只能单开一列,每一列的最上层数字也没有改变,所以对于之后所有的数字,他们的相对位置(放在哪个球上面/单开一列)没有任何变化,解不会变差。

    2.既然只是相邻组成平方数,那就没必要考虑下面的球的编号,只需储存最上面球的编号即可判断某个球能否放在这根柱子上

    #include<cstdio>
    int n,i,t=1,book=1;
    int s[105];
    int pd(int x)
    {
      for(int j=1;j*j<=x;j++)
      {
        if(j*j==x) return 1;
      }
      return 0;
    }
    int main()
    {
      scanf("%d",&n);
      while(book==1)
      {
        book=0;
        for(i=1;i<=n;i++)
        {
         if(pd(t+s[i])==1)
          {
            s[i]=t;
            t++;
            book=1;
            break; 
          }
          if(s[i]==0)
          {
            s[i]=t;
            t++;
            book=1;
            break;
          }
        }
      }
      printf("%d",t-1);
      return 0;
    }
  • 相关阅读:
    Hibernate 中 get()和load()的区别
    Socket网络编程
    经典
    jsp的九大内置对象及EL表达式的隐含对象
    TreeSet
    centos7.4安装npm
    centos7.4中安装docker
    centos7安装nginx
    centos中安装基础环境
    在docker中安装mysql
  • 原文地址:https://www.cnblogs.com/zeroform/p/7115044.html
Copyright © 2020-2023  润新知