HOJ12138

来源:互联网 发布:淘宝上万斯正品有哪些 编辑:程序博客网 时间:2024/06/05 10:58

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<math.h>
#define inf 0x3f3f3f
using namespace std;
int dp1[1000001],dp2[1000001];
int main()
{
    int a[200],b[200],t,test,m,ans,res,h;
    a[0] = 0;t = 1;
    for(int i = 1;a[i-1] <=1000000;i++)
      {
         a[i] = (i + 2)*(i + 1)*i / 6;
         if(a[i] % 2 != 0)
           {
              b[t] = a[i];
              t++;
           }
      }
      dp1[0] = 0;
      dp2[0] = 0;
      for(int i = 1 ;i<=1000000;i++)
            {
                dp1[i] = inf;
                dp2[i] = inf;
                for(int j = 1 ;i >= a[j]; j++)
                  {
                     m = dp1[i - a[j]] + 1;
                     if(m < dp1[i])
                       dp1[i] = m;
                  }
               
                for(int j = 1 ; i >= b[j]; j++)
                  {
                     m = dp2[i - b[j]] + 1;
                     if(m < dp2[i])
                       dp2[i] = m;
                  }
            }
    while(scanf("%d",&test) && test != 0)
      {
         
         
          printf("%d %d\n",dp1[test],dp2[test]);
      }
    
    
   
return 0;  
}
本题最开始想的是从最后一个取然后一直往前走,找到%为0的点。仔细一想这个其实就是和从1开始的贪心一样的。今天听到学长讨论,贪心的话,必须是超递增数列,所谓超递增数列的话就是第i项比前i-1项的和还要大,今天听到的这个思想感觉比较重要,以后遇到超递增的时候使用贪心应该能够很快解题。

而作为不是超递增的又是数列的话,要能够想到用搜索或者是DP去解决,不要想一些肥猪流的思路出来。

还有一点就是这里最开始是把dp的处理放在while循环里面 是超时,不行。然后放在外面去先打一个DP的表。以后要养成这种思维,先打表,直觉感觉可能按照test的大小再打表要小一点,但是样例都是很多的,所以在输入样例的时候进行O(1)的查询就可以了

原创粉丝点击