问题 B: 习题6-12 解密 时间限制: 1 Sec 内存限制: 12 MB 提交: 50 解决: 31 外部导入 提交状态讨论版 题目描述 有一行电文,已按以下规律译成密码: A-->Z a-->z B-->Y b-->y C-->X c-->x ...... ...... 即第一个字母变成第26个字母,第i个字母变成第(26-i+1)个字母,非字母字符不变。要求根据密码译回原文,并输出。 输入 输入一行密文 输出 解密后的原文,单独占一行。 样例输入 Copy ZYX123zyx 样例输出 Copy ABC123abc
int main() { string s; while(cin>>s) { int len,i; len=s.size(); for(i=0;i<len;i++) { if(s[i]=='Z') { s[i]='A'; } else if(s[i]=='z') { s[i]='a'; } else if(s[i]>='B'&&s[i]<='Y') { s[i]=155-s[i]; } else if(s[i]>='b'&&s[i]<='y') { s[i]=219-s[i]; } } cout<<s<<endl; } return 0; }
问题 C: 数字三角形之备忘录法 时间限制: 1 Sec 内存限制: 128 MB 提交: 2 解决: 0 201501010119 提交状态讨论版 题目描述 以下图所示的数字三角形,从三角形的顶部到底部有不少条不一样的路径。对于每条路径,把路径上面的数加起来能够获得一个和,和最大的路径称为最佳路径。编写一个程序求出最佳路径上的数字之和。 【使用备忘录法实现】 7 3 8 8 1 2 2 7 4 4 4 5 2 6 5 输入 多组样例输入,每组第一行输入三角形的层数n,接下来n行输入三角形。 输出 输出最佳路径上的数字之和。 样例输入 Copy 2 1 1 2 3 1 1 2 1 2 3 样例输出 Copy 3 6 提示 路径上的每一步只能从一个数走到下一层上和它最近的左边的数或者右边的数。
using namespace std; int a[105][105],p[105][105],n; int s(int i,int j) { if(p[i][j]>=0) //若是计算过了 return p[i][j]; if(i==n+1) //p虽然是第i行,可是最下面一行已经算过了,因此这是结束递归的条件 return 0; else return p[i][j]=a[i][j]+max(s(i+1,j),s(i+1,j+1)); //规律,a[i][j](处于i,j位置的数组元素a,)加上它正下方的元素和斜下方的元素取最大=》最优子结构,从一开始就取最大值 } int main() { while(cin>>n) { for(int i=1;i<=n;i++) //注意输入的数组为三角形状,因此不要搞混i,j的取值 for(int j=1;j<=i;j++) cin>>a[i][j]; memset(p,-1,sizeof(p)); //把p置为-1 s(1,1); //下标从1开始 cout<<p[1][1]<<endl; } return 0; }
以上为备忘录法;数组
p数组用来记录是否算过路径;由于最初的想法就是从最上部一直递归到最下面,可是这样时间复杂度很大,因此用一个数组来存是否算过这条路;spa
递归从(1,1)开始,可是一直递归到最下面那一层,当递归结束的时候开始返回上一层(计算结果),可是在返回上一层的时候不少数咱们是重复计算过的,因此咱们须要一个数组来备忘 记录咱们是否算过这个数,code
动态规划法blog
从底向上找最优解递归
int a[105][105],p[105][105],n; int s() { for(int j=1;j<=n;j++) p[n][j]=a[n][j]; //把a最后一行的值给p的最后一行 for(int i=n-1;i>=1;i--) //自底向上 for(int j=1;j<=i;j++) p[i][j]=a[i][j]+max(p[i+1][j],p[i+1][j+1]); //其实从备忘录法已经能够猜到dp规律了 return 0; } int main() { while(cin>>n) { for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) cin>>a[i][j]; memset(p,-1,sizeof(p)); s(); cout<<p[1][1]<<endl; } return 0; }