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; }