#include
using namespace std;
void solve()
{
int n;
cin>>n;
if(n==1||n==3||n==6||n==10||n==15)
{
cout<<1<<endl;
return;
}
int cnt=0;
if(n>=100)
{
int temp=n/15;
if(temp>=6)
{
n-=(temp-6)*15;
cnt+=temp-6;
}
}
while(n)
{
while(n>=30)
{
n-=15;
cnt++;
}
if(n==29)
{
n-=29;
cnt+=4;
}
if(n==28)
{
n-=28;
cnt+=3;
}
if(n==27)
{
n-=27;
cnt+=3;
}
if(n==26)
{
n-=26;
cnt+=3;
}
if(n==25)
{
n-=25;
cnt+=2;
}
if(n==24)
{
n-=24;
cnt+=3;
}
if(n==23)
{
n-=23;
cnt+=3;
}
if(n==22)
{
n-=22;
cnt+=3;
}
if(n==21)
{
n-=21;
cnt+=2;
}
if(n==20)
{
n-=20;
cnt+=2;
}
if(n==19)
{
n-=19;
cnt+=3;
}
while(n>=18)
{
n-=18;
cnt+=2;
}
if(n==17)
{
n-=17;
cnt+=3;
}
if(n==16)
{
n-=16;
cnt+=2;
}
while(n>=15)
{
n-=15;
cnt+=1;
}
while(n>=14)
{
n-=14;
cnt+=3;
}
if(n==13)
{
n-=13;
cnt+=2;
}
while(n>=12)
{
n-=12;
cnt+=2;
}
if(n==11)
{
n-=11;
cnt+=2;
}
while(n>=10)
{
n-=10;
cnt++;
}
if(n==9)
{
n-=9;
cnt+=2;
}
if(n==8)
{
n-=8;
cnt+=3;
}
if(n==7)
{
n-=7;
cnt+=2;
}
while(n>=6)
{
n-=6;
cnt++;
}
if(n==5)
{
n-=5;
cnt+=3;
}
if(n==4)
{
n-=4;
cnt+=2;
}
while(n>=3)
{
n-=3;
cnt++;
}
if(n==2)
{
n-=2;
cnt+=2;
}
while(n>=1)
{
n-=1;
cnt++;
}
}
cout<<cnt<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--)
solve();
return 0;
}
其实可以把这些情况存到数组里面直接输出就好了,但是我比赛的时候先是写了一下条件判断,然后加了一些条件判断,最后索性全部条件判断了
#include
using namespace std;
int a[100]={0,1,2,1,2,3,1,2,3,2,1,2,2,2,3,1,2,3,2,3,2,2,3,3,3,2,3,3,3,4,2};
void solve()
{
int n;
cin>>n;
if(n<=30)
cout<<a[n]<<endl;
else
{
int ans=0;
if(n>=100)
{
int temp=n-100;
int temp2=temp/15;
int temp3=15*temp2;
ans+=temp2;
n-=temp3;
}
while(n>=30)
{
n-=15;
ans++;
}
ans+=a[n];
cout<<ans<<endl;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--)
solve();
return 0;
}
不管怎么优化,还是太笨了,这个做法,而且具有一定的风险
枚举每一次数字的答案的时候,可能枚举错误
但总归是可以过的,夸夸自己
#include
using namespace std;
void solve()
{
int n;
cin>>n;
int ans=1e9;
for(int one=0;one<=2;one++)
for(int three=0;three<=1;three++)
for(int six=0;six<=4;six++)
for(int ten=0;ten<=2;ten++)
{
int temp=1*one+3*three+6*six+10*ten;
int temp2=n-temp;
if(temp<=n&&temp2%15==0)
ans=min(ans,one+three+six+ten+temp2/15);
}
cout<<ans<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--)
solve();
return 0;
}
上面这种解法表示的是,1 最多只可以使用 2 次,3 最多只可以使用 1 次,6 最多只可以使用 4 次,10 最多只可以使用 2 次
很简单,假设只用 3 次 1 ,为什么不直接用 3
假设用 2 次 3 为什么不直接用 6
假设用 5 次 6 为什么不直接用 2 个 15
假设用 3 个 10 为什么不直接用 2 个 15
也就是说,有点找最小公倍数的感觉,算是一个数学做法,枚举暴力求解就行,需要注意的是,条件判断要保证枚举的答案在范围内,少加一个判断条件会发生部分错误
还有一些 dp 的解法,我现在还是不管比较好