除法(Division,uva725)

输入整数n,按从小到大的顺序输出所有形如abcde/fghij=n的表达式,其中a~j恰好为数字0~9的一个排列(可以有前导0),2<=n<=79。

输入:输入若干组数据,以文件结束符结束。

输出:For each test case you must print the message: Case #M: The maximum product is P., where M is the number of the test case, starting from 1, and P is the value of the maximum product. After each test case you must print a blank line.

样例输入:

62

样例输出:

79546/01283=62

94736/01528=62

方法1:利用3重循环枚举起点和终点。

错误程序:

#include<iostream>
#include<cstdio>
using namespace std;
int a[30];
int main(){
 int n,m=0;
 while (cin>>n){
  m++;
 long long maxc=0,s; 
 for(int i=1;i<=n;i++) cin>>a[i];
 for (int i=1;i<=n;i++){
  for (int j=i+1;j<=n;j++){//程序错误:考虑不全,当单个数为最大值时,(更没有考虑到,当第n个数为最大值的情况),不能出正确结果
   s=a[i];
   for (int k=i+1;k<=j;k++)s=s*a[k];
   if (s>maxc) maxc=s;
  }
  
 }
  cout<<"Case #"<<m<<": The maximum product is "<<maxc<<"."<<endl<<endl;
 }
 return 0;
 
}

修改1:

for (int i=1;i<=n;i++){
for (int j=i;j<=n;j++){
s=a[i];
if (s>maxc) maxc=s;
for (int k=i+1;k<=j;k++)s=s*a[k];
if (s>maxc) maxc=s;
}
}

继续修改:

for (int i=1;i<=n;i++){
for (int j=i;j<=n;j++){
s=1;
for (int k=i;k<=j;k++)s=s*a[k];
if (s>maxc) maxc=s;
}
}

简化:由三重循环修改为二重

for (int i=1;i<=n;i++){
  s=1;
  for (int j=i;j<=n;j++){
    s=s*a[j];//累乘即可
  if (s>maxc) maxc=s;
  }
}

继续简化:能不能用一维实现

思路,动态规划,模拟加法的最长连续子序列 f[i]=max(f[i-1],a[i]),则有:

因为本题是乘法,需要如果只单纯记录最大值是不妥当的,因为负数的最小值*负数结果也可能最大。所以有:

f[i]=max(max(f[i-1]*a[i],g[i-1]*a[i]),a[i]);
g[i]=min(min(f[i-1]*a[i],g[i-1]*a[i]),a[i]); 

 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long f[30],g[30],a[30];
int main(){
int n,m=0;
while (cin>>n){
m++;
long long maxc=0,s;
for(int i=1;i<=n;i++) cin>>a[i];
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
for (int i=1;i<=n;i++){
f[i]=max(max(f[i-1]*a[i],g[i-1]*a[i]),a[i]);
g[i]=min(min(f[i-1]*a[i],g[i-1]*a[i]),a[i]);
}
for(int i=1;i<=n;i++)if (maxc<f[i]) maxc=f[i];
cout<<"Case #"<<m<<": The maximum product is "<<maxc<<"."<<endl<<endl;
}
return 0;
}

 符:算法竞赛入门经典例题7—2