#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node
{
int spend;
char big[100];
};
struct node ans[5010]={{0}};
void add(char *a,char *b) //大数加法
{
char sum[100]={0};
int len1 = strlen(a);//数a的长度
int len2 = strlen(b);//数b的长度
int i = len1-1,j = len2-1,temp = 0,carryIn = 0;//初始进位为/从最后一位开始做加法
int count=0;
int f;
while(i>=0&&j>=0)
{
temp = a[i]-'0'+b[j]-'0'+carryIn;//计算当前位
sum[count++] = temp%10+'0';
carryIn = temp/10;//计算进位
--i;
--j;
}
//第一个数还有剩余
if(i>=0)
{
//利用进位继续做
while(i>=0)
{
temp = a[i]-'0'+carryIn;
sum[count++] = temp%10+'0';
carryIn = temp/10;
--i;
}
}
//第二个数还有剩余
if(j>=0)
{
while(j>=0)
{
temp = b[j]-'0'+carryIn;
sum[count++] = temp%10+'0';
carryIn = temp/10;
--j;
}
}
//最高位特殊考虑下
if(carryIn>0)
{
sum[count++] = '1';
}
f=0;
for(i=count-1;i>=0;i--)
a[f++]=sum[i];
}
void deal(int n ,long *a) //n表示天数,a表示花费数组
{
int i ,j;
int max;
int flag;
for(i=1;i<n;i++)
{
max=flag=0;
for(j=i-1;j>=0;j--)
{
if(a[i]<a[j])
{
flag=1;
max=max>ans[j].spend?max:ans[j].spend;
}
if(a[j]==a[i]) //去重。因为如果有相同的数字的话,那么前面的一定比后面的少
{ //将其置0就好
ans[j].spend=0;
memset(ans[j].big,0,sizeof(ans[j].big));
}
}
if(!flag)
{
ans[i].spend=1;
ans[i].big[0]='1';
}
else
{
for(j=0;j<i;j++)
{
if(a[i]<a[j]&&ans[j].spend==max)
{
ans[i].spend=max+1;
add(ans[i].big,ans[j].big);
}
}
}
}
}
int main()
{
FILE *fin=fopen("buylow.in","r");
FILE *fout=fopen("buylow.out","w");
int daynum;
long price[5010]={0};
int i;
int maxnum=0;
char maxway[100]={0};
fscanf(fin,"%d",&daynum);
for(i=0;i<daynum;i++)
fscanf(fin,"%ld",&price[i]);
ans[0].spend=1;
ans[0].big[0]='1';
deal(daynum,price);
for(i=0;i<daynum;i++)
maxnum=maxnum>ans[i].spend?maxnum:ans[i].spend;
for(i=0;i<daynum;i++)
{
if(ans[i].spend==maxnum)
add(maxway,ans[i].big);
}
fprintf(fout,"%d ",maxnum);
for(i=0;maxway[i];i++)
fprintf(fout,"%c",maxway[i]);
fprintf(fout,"\n");
return 0;
}
注意要用高精度运算。。