题目:点击打开链接
题意:I=1, V=5, X=10, L=50,n个位置可任意放4个数,n个数组成的值是每一位的值的和,要求最后代表的值不同的种类数。
分析:看起来没有什么特别的算法能解决,只能暴力打表找规律了,我开始代码写的太搓了,用的set+dfs,复杂度(n^4*logn),只打出了前12个根本没找出规律,后面参考了下别人的代码,发现直接3个for循环暴力枚举每个数出现的次数就行了,复杂度为O(n^3)。发现第11项以后,每一项的值比前面一项多49,构成等差数列,理论上解释是之后已经足够稠密到可以每次多拼出49个数字。还是第一次见到要到十多项才有规律的题。。。
题意:I=1, V=5, X=10, L=50,n个位置可任意放4个数,n个数组成的值是每一位的值的和,要求最后代表的值不同的种类数。
分析:看起来没有什么特别的算法能解决,只能暴力打表找规律了,我开始代码写的太搓了,用的set+dfs,复杂度(n^4*logn),只打出了前12个根本没找出规律,后面参考了下别人的代码,发现直接3个for循环暴力枚举每个数出现的次数就行了,复杂度为O(n^3)。发现第11项以后,每一项的值比前面一项多49,构成等差数列,理论上解释是之后已经足够稠密到可以每次多拼出49个数字。还是第一次见到要到十多项才有规律的题。。。
打表代码:
#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define MOD 1000000007
#define PI acos(-1.0)
const int N = 1e6+10;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
ll n,ans;
int a[50],k,cnt[1000];
set<int> s;
void dfs(int x,int v) {
a[x]=v;
if(x==k) {
int sum=0;
for(int j=1;j<=k;j++) {
if(a[j]==1) sum+=1;
else if(a[j]==2) sum+=5;
else if(a[j]==3) sum+=10;
else if(a[j]==4) sum+=50;
}
if(!cnt[sum]) cnt[sum]=1,ans++;
///s.insert(sum);
return ;
}
for(int i=1;i<=4;i++)
dfs(x+1,i);
}
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
for(k=1;k<=15;k++)
mst(cnt,0),dfs(0,0),cout<<ans<<endl,ans=0;
return 0;
}
优化后的打表代码:
#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define MOD 1000000007
#define PI acos(-1.0)
const int N = 1e6+10;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n,ans;
int cnt[100000];
ll sv(int x) {
ll ans=0;
mst(cnt,0);
for(int i=0;i<=x;i++)
for(int j=0;j<=x-i;j++)
for(int k=0;k<=x-i-j;k++)
if(!cnt[i+5*j+10*k+50*(x-i-j-k)]) ans++,cnt[i+5*j+10*k+50*(x-i-j-k)]=1;
return ans;
}
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
for(int i=1;i<=20;i++)
cout<<sv(i)<<endl;
return 0;
}
AC代码:
#pragma comment(linker, "/STACK:102400000,102400000")///ÊÖ¶¯À©Õ»
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define MOD 1000000007
#define PI acos(-1.0)
const int N = 1e6+10;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
ll n,ans;
int a[50],k,cnt[1000];
set<int> s;
ll sv(int x) {
ll ans=0;
mst(cnt,0);
for(int i=0;i<=x;i++)
for(int j=0;j<=x-i;j++)
for(int k=0;k<=x-i-j;k++)
if(!cnt[i+5*j+10*k+50*(x-i-j-k)]) ans++,cnt[i+5*j+10*k+50*(x-i-j-k)]=1;
return ans;
}
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
if(n<12) cout<<sv(n)<<endl;
else cout<<sv(11)+(n-11)*49<<endl;
return 0;
}