题意:好难表达...
分析:dp了,没什么好说的,dp[now]=min{dp[i]+dp[now-i],dp[i]+dp[now/i]且now%i==0,dp[i]+dp[j]且i^j==now;} 。不过转移的时候我的方法很暴力,不知道其他优秀的方法是怎么做的。 一些很明显的值的表达式可以预处理出来。
分析:dp了,没什么好说的,dp[now]=min{dp[i]+dp[now-i],dp[i]+dp[now/i]且now%i==0,dp[i]+dp[j]且i^j==now;} 。不过转移的时候我的方法很暴力,不知道其他优秀的方法是怎么做的。 一些很明显的值的表达式可以预处理出来。
#include
<
iostream
>
#include < stdio.h >
#include < memory.h >
#include < cmath >
using namespace std;
#define inf 2000000000
struct node
{
int num;
char s[100];
} a[ 20010 ];
void ini()
{
int i,now,j,tem,cnt;
for(i=1;i<=20000;i++) a[i].num=inf;
a[1].num=1; strcpy(a[1].s,"1"); // 1,2,3,5,7预处理出来
a[2].num=1; strcpy(a[2].s,"2");
a[3].num=1; strcpy(a[3].s,"3");
a[5].num=1; strcpy(a[5].s,"5");
a[7].num=1; strcpy(a[7].s,"7");
a[4].num=2; strcpy(a[4].s,"(2^2)"); // 4也预处理
a[6].num=1; strcpy(a[6].s,"3!"); // 预处理3到7的阶乘,因为8的阶乘已经超过20000了
a[24].num=2; strcpy(a[24].s,"(2^2)!"); // 注意阶乘的表达式外面就不用括号了,我一开始加了就wa
a[120].num=1; strcpy(a[120].s,"5!");
a[720].num=1; strcpy(a[720].s,"3!!");
a[5040].num=1; strcpy(a[5040].s,"7!");
for(now=4;now<=20000;now++) // 下面就是dp了 转移的时候很暴力
{
if(a[now].num!=inf) continue;
tem=(int)sqrt(now+0.0);
for(i=2;i<=tem;i++)
{
if(now%i==0)
{
j=now/i;
if(a[i].num+a[j].num<a[now].num) // *运算
{
a[now].num=a[i].num+a[j].num;
strcpy(a[now].s,"(");
strcat(a[now].s,a[i].s);
strcat(a[now].s,"*");
strcat(a[now].s,a[j].s);
strcat(a[now].s,")");
}
cnt=now; j=0;
while(cnt%i==0&&cnt>0)
{
++j;
cnt/=i;
}
if(cnt==1)
{
if(a[i].num+a[j].num<a[now].num) // ^运算
{
a[now].num=a[i].num+a[j].num;
strcpy(a[now].s,"(");
strcat(a[now].s,a[i].s);
strcat(a[now].s,"^");
strcat(a[now].s,a[j].s);
strcat(a[now].s,")");
}
}
}
}
for(i=1;i<=now/2;i++)
{
j=now-i;
if(a[i].num+a[j].num<a[now].num) // +运算
{
a[now].num=a[i].num+a[j].num;
strcpy(a[now].s,"(");
strcat(a[now].s,a[i].s);
strcat(a[now].s,"+");
strcat(a[now].s,a[j].s);
strcat(a[now].s,")");
}
}
}
}
int main()
{
ini();
int n;
while(scanf("%d",&n)!=EOF)
{
printf("%s\n",a[n].s);
}
return 0;
}
#include < stdio.h >
#include < memory.h >
#include < cmath >
using namespace std;
#define inf 2000000000
struct node
{
int num;
char s[100];
} a[ 20010 ];
void ini()
{
int i,now,j,tem,cnt;
for(i=1;i<=20000;i++) a[i].num=inf;
a[1].num=1; strcpy(a[1].s,"1"); // 1,2,3,5,7预处理出来
a[2].num=1; strcpy(a[2].s,"2");
a[3].num=1; strcpy(a[3].s,"3");
a[5].num=1; strcpy(a[5].s,"5");
a[7].num=1; strcpy(a[7].s,"7");
a[4].num=2; strcpy(a[4].s,"(2^2)"); // 4也预处理
a[6].num=1; strcpy(a[6].s,"3!"); // 预处理3到7的阶乘,因为8的阶乘已经超过20000了
a[24].num=2; strcpy(a[24].s,"(2^2)!"); // 注意阶乘的表达式外面就不用括号了,我一开始加了就wa
a[120].num=1; strcpy(a[120].s,"5!");
a[720].num=1; strcpy(a[720].s,"3!!");
a[5040].num=1; strcpy(a[5040].s,"7!");
for(now=4;now<=20000;now++) // 下面就是dp了 转移的时候很暴力
{
if(a[now].num!=inf) continue;
tem=(int)sqrt(now+0.0);
for(i=2;i<=tem;i++)
{
if(now%i==0)
{
j=now/i;
if(a[i].num+a[j].num<a[now].num) // *运算
{
a[now].num=a[i].num+a[j].num;
strcpy(a[now].s,"(");
strcat(a[now].s,a[i].s);
strcat(a[now].s,"*");
strcat(a[now].s,a[j].s);
strcat(a[now].s,")");
}
cnt=now; j=0;
while(cnt%i==0&&cnt>0)
{
++j;
cnt/=i;
}
if(cnt==1)
{
if(a[i].num+a[j].num<a[now].num) // ^运算
{
a[now].num=a[i].num+a[j].num;
strcpy(a[now].s,"(");
strcat(a[now].s,a[i].s);
strcat(a[now].s,"^");
strcat(a[now].s,a[j].s);
strcat(a[now].s,")");
}
}
}
}
for(i=1;i<=now/2;i++)
{
j=now-i;
if(a[i].num+a[j].num<a[now].num) // +运算
{
a[now].num=a[i].num+a[j].num;
strcpy(a[now].s,"(");
strcat(a[now].s,a[i].s);
strcat(a[now].s,"+");
strcat(a[now].s,a[j].s);
strcat(a[now].s,")");
}
}
}
}
int main()
{
ini();
int n;
while(scanf("%d",&n)!=EOF)
{
printf("%s\n",a[n].s);
}
return 0;
}