Codeforces 997B Roman Digits(半打表)

题意:I=1, V=5, X=10, L=50,n个位置可任意放4个数,n个数组成的值是每一位的值的和,要求最后代表的值不同的种类数。

缺欠的是做题的思路,当看到这道题发现n是10^9级别,第一反应是得找到一个公式。但怎么找没想出来。

满足i+j+k+p = n (i,j,k,p分别是1,5,10,50取的个数),我们可以用n^3代价(枚举i,j,k)n比较小的时候的答案,并试着从枚举得到的答案里找到规律。

事实也确实能从中找到规律,n从12开始就是等差数列了,方差49

#include <bits/stdc++.h>

using namespace std;

int a[]={1,5,10,50};
long long num=0;


int dfs(int n)
{
    map<long long,int>mp;
    mp.clear();
    num=0;
    for(int i=0;i<=n;i++)
    {
        for(int j=0;i+j<=n;j++)
        {
            for(int k=0;i+j+k<=n;k++)
            {
                int l=i+j*5+k*10+(n-i-j-k)*50;
                if(l>=0&&!mp[l]) {num++;mp[l]=1;}
            }
        }
    }
    return num;
}
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);
    long long n;
    cin>>n;
    if(n<=20) cout<<dfs(n)<<endl;
    else cout<<(dfs(20)+(n-20)*49)<<endl;

    return 0;
}

 

posted @ 2018-08-20 01:22  Somnus、M  阅读(124)  评论(0编辑  收藏  举报