172210704111-陈国佳总结《2017年12月18日》【连续069天】
标题:动态规划例题:数字三角形和输入输出流相关的类;
内容:
A.例题:数学三角形
描述7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (图1)
图1给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的那个数或者右边的那个数。
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
30
解题:
#include<iostream>
#include<algorithm>
#define MAX 101
using namespace std;
int D[MAX][MAX];
int n;
int MaxSum(int i,int j){
if(i==n)
return D[i][j];
int x=MaxSum(i+1,j);
int y=MaxSum(i+1,j+1);
return max(x,y)+D[i][j];
}
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin>>D[i][j];
cout<<MaxSum(1,1)<<endl;
}
该程序理论上可解,但超时,由于重复计算,其复杂度达到了2^n,而n到100时,必定超时;
解决方法:采用动归:
int maxSum[MAX][MAX];
int n;
int MaxSum(int i,int j){
if(maxSum[i][j]!=-1)
return maxSum[i][j];
for(i=1;i<=n;i++)
for(j=1;j<=i;j++){
cin>>D[i][j];
maxSum[i][j]=-1;
}
这样通过判断maxSum[i][j]是否被计算过来减少重复计算;
更简单的方法:递推
#include<iostream>
#include<algorithm>
#define MAX 101
using namespace std;
int D[MAX][MAX];
int maxSum[MAX][MAX];
int n;
int main()
{
int i,j;
cin>>n;
for(i=1;j<=i;j++)
for(j=1;j<=i;j++)
cin>>D[i][j];
for(int i=1;i<=n;++i)
maxSum[n][i]=D[n][i];
for(int i=n-1;i>=1;--i)
for(int j=1;j<=i;++j)
maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j];
cout<<maxSum[1][1]<<endl;
}
空间优化:可以放弃二维数组maxSum,直接用一维数组便可实现数据的储存;
进一步优化:直接用D的第n行便可;
int*maxSum;
maxSum=D[n]; //maxSum指向第n行
for(int i=n-1;i>=1;--i)
for(int j=1;j<=i;++j)
maxSum[j]=max(maxSum[j],maxSum[j+1])+D[i][j];
cout<<maxSum[1]<<endl;
B.
1.
istream:输入的流类,cin就是该类的对象;
ostream:输出的流类,cout就是该类的对象;
ifstream:从文件中读取数据的类;
ofstream:向文件写入数据的类;
iostream:既能输入,又能输出的类;
fstream:即能从文件读取数据,又能写入数据的类;
2.
输入流对象:cin 与标准输入设备相连;
输出流对象:cout 与标准输出设备相连;
cerr 与标准错误输出设备相连; //用于向屏幕输出出错信息;
clog 与标准错误输出设备相连;
缺省情况下,cerr/clog与cout一样;
判断输入流结束:
while(cin>>x){}
1)从键盘输入时,在单独一行输入Ctrl+Z代表输入流结束;
2)从文件输入,如果前有freopen("some.txt","r",stdin);
则读到文件尾部,输入流就算结束;
3.istream类的成员函数:
istream & getline(char *buf,int bufSize);
从输入流中读取bufSize-1个字节到缓冲区buf,或读到‘\n’为止;
istream & getline(char *buf,int bufSize,char delim);
从输入流中读取bufSize-1个字节到缓冲区buf,或读到delim字节为止;
#include<iostream>
using namespace std;
int main()
{
int x;
char buf[100];
cin>>x;
cin.getline(buf,90);
cout<<buf<<endl;
return 0;
}
该程序,如果输入的是12 abcd回车;
int main()
{
int x,y;
cin>>x>>y;
freopen("test.txt","w",stdout); //标准输出重定向到test.txt文件
if(y==0) //除数为0则在屏幕上输出错误信息
cerr<<"error."<<endl;
else
cout<<x/y; //结果输出到text.txt
return 0;
}
5.输入重定向:
int main()
{
double f;
int n;
freopen("test.txt","r",stdin); //cin到test.txt中 读取数据
cin>>f>>n;
cout<<f<<","<<n<<endl;
return 0;
}
当text.txt文件内容为 3.14 123
则输出 3.14 123
明日计划:学习动态规划;