码迷,mamicode.com
首页 > 其他好文 > 详细

topcoder srm 687 div1

时间:2017-06-05 21:02:19      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:tin   names   nap   most   lap   using   替换   stdio.h   code   

1、$A_{1}=2,A_{2}=3,A_{n}=A_{n-2}+A_{n-1}-1$。给出数字$n$,将其表示成若干个$A$中的不同元素的和。

思路:设$B_{n}=A_{n}-1$,那么有$B_{n}=B_{n-2}+B_{n-1},B_{1}=1,B_{2}=2$。那么$B$其实是斐波那契数列。设将$n$表示成$k$个$A$中的元素,那么就等同于将$n-k$表示成$k$个$B$中不同的元素。这个分两步进行:(1)将$n-k$表示成最少的$B$中元素的和,(2)如果这个个数大于$k$那么无解。若小于$k$,可以将某个数字$x=B_{t}$替换为$B_{t-2}+B_{t-1}$以增加一个数字。

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
using namespace std;


long long f[100];
int n;

void init(long long x)
{
    f[1]=1;
    f[2]=2;
    for(int i=3;i<100;++i)
    {
        f[i]=f[i-1]+f[i-2];
        if(f[i]>x)
        {
            n=i-1; break;
        }
    }
}

vector<int> ans;



int check(int k,long long x)
{
    if(x<=0) return 0;
    ans.clear();
    while(x>0)
    {
        for(int i=n;i>=1;--i) if(x>=f[i])
        {
            ans.push_back(i);
            x-=f[i];
            break;
        }
    }
    if((int)ans.size()>k) return 0;
    while((int)ans.size()<k)
    {
        sort(ans.begin(),ans.end());
        int ok=0;
        for(int i=0;i<(int)ans.size();++i)
        {
            if((i==0&&ans[0]>=3)||(i!=0&&ans[i]-ans[i-1]>=3))
            {
                ans.push_back(ans[i]-1);
                ans[i]-=2;
                ok=1;
                break;
            }
        }
        if(!ok) return 0;
    }
    return 1;
}

class AlmostFibonacciKnapsack
{
public:
	vector<int> getIndices(long long x)
	{
	    init(x);
	    for(int i=1;i<=n;++i) if(check(i,x-i)) return ans;
	    return vector<int>{-1};
	}
};

  

topcoder srm 687 div1

标签:tin   names   nap   most   lap   using   替换   stdio.h   code   

原文地址:http://www.cnblogs.com/jianglangcaijin/p/6946902.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!