POJ_S1E02_Recursion&DP(2)

来源:互联网 发布:windows程序设计书籍 编辑:程序博客网 时间:2024/06/05 06:13
OUTLINE:
文件结构“图”
放苹果问题
拦截导弹问题
最大子矩阵
古代密码//此题乃乱入的基础题,@@关键@@……读懂题意,字符频率一致即“YES”
Basic idea:
文件结构图:
1.抓住返回条件
2.prefix应当设为局部变量
3.读入char 时格外注意空格回车的处理及处理顺序
4.贴!代!码!—— main函数里freopen("putout.txt", "w", stdout);……fclose(stdout);//关闭
#include <stdio.h>#include <string>#include <iostream>#include <deque>#include <algorithm>using namespace std;//putin & putoutvoid BuildDir(int level){if (level == 0)printf("ROOT\n");string prefix = "";for (int i = 0; i < level; ++i)prefix += "|     ";string nextstr;deque<string> files;while (1){cin >> nextstr;char c = nextstr.c_str()[0];if (c == 'd'){cout << "|     " << prefix << nextstr << endl;BuildDir(level + 1);}else if (c == 'f')files.push_back(nextstr);else{sort(files.begin(), files.end());while (!files.empty()){cout << prefix << files.front() << endl;files.pop_front();}return;}}//whilereturn;}int main(){//freopen("putout.txt", "w", stdout);char c;int test = 1;while (1){printf("DATA SET %d:\n", test);BuildDir(0);cout << endl;cin.get(); c = cin.peek();if (c == '#')break;++test;}//fclose(stdout);//关闭return 0;}
全部读入后再输出的代码:
#include <iostream>#include <stdio.h>#include <string.h>#include <string>#include <vector>#include <algorithm>using namespace std;class MYDIRS{public:MYDIRS(string name_) :name_dires(name_){}MYDIRS(){}string name_dires;vector<MYDIRS> dirs;vector<string>files;};int num_data = 0;bool INPUT(MYDIRS *dir_){string tmp;cin >> tmp;if (tmp == "#")return false;while (tmp != "]" && tmp != "*"){if (tmp[0] == 'f')dir_->files.push_back(tmp);else{dir_->dirs.push_back(tmp);INPUT(&dir_->dirs.back());}cin >> tmp;}//whileif (tmp == "*")++num_data;return true;}void OUTPUT(MYDIRS *dir_,int CTR){for (int i = 0; i < CTR; ++i){printf("|     ");}cout << dir_->name_dires << endl;while (!dir_->dirs.empty()){OUTPUT(&dir_->dirs.front(), CTR + 1);//recursiondir_->dirs.erase(dir_->dirs.begin());}sort(dir_->files.begin(), dir_->files.end());while (!dir_->files.empty()){for (int i = 0; i < CTR; ++i){printf("|     ");}cout << dir_->files.front() << endl;dir_->files.erase(dir_->files.begin());}return;}int main(){num_data = 0;MYDIRS *DIR = new MYDIRS("ROOT");while (INPUT(DIR)){printf("DATA SET %d:\n", num_data);OUTPUT(DIR, 0);printf("\n");}return 0;}
放苹果问题:->整数的划分
1.dp[i][j]——i个苹果放到j个盘子里,有空盘+没空盘
2.这段代码一定要背下来,熟练掌握
#include <stdio.h>int slv(int napples,int nplates){if(napples==0||nplates==1)return 1;if(nplates>napples)return slv(napples,napples);return slv(napples,nplates-1)+slv(napples-nplates,nplates);}int main(){int t,M,N;//M_apples,N_platesscanf("%d",&t);while(t--){scanf("%d%d",&M,&N);printf("%d\n",slv(M,N));}return 0;}
DP写法:
#include <stdio.h>using namespace std;int main(){int slv[60][60]={0};slv[0][0]=1;slv[1][1]=1;for(int i=0;i<=50;++i){for(int j=1;j<=50;++j){if(i>=j)slv[i][j]=slv[i][j - 1]+slv[i-j][j];elseslv[i][j]=slv[i][i];}}int n=0;while(scanf("%d",&n)!=EOF)printf("%d\n",slv[n][n]);return 0;}

导弹拦截问题:
1.最大下降子列问题
2.基本思路——dp[i]:以第i个元素结尾的最长下降子列长度
dp[i]=max{1,dp[j]+1}
jfrom 1 to i-1 &&height[j]>=height[i]
dp[0] = 1000000;for (i = 1; i <= k; ++i){scanf("%d", &height[i]);dp[i] = 1;for (j = i - 1; j >= 0; --j){if (height[j] >= height[i])dp[i] = max(dp[i], dp[j] + 1);}}mymax = dp[1];for (i = 2; i <= k; ++i)mymax = max(mymax, dp[i]);
3.降为的奇葩思路——dp[i]:当前,长度为i的下降子列的最大末位元素
dp[0] = 1000000;for (i = 1; i <= k; ++i){scanf("%d", &height[i]);if (i == 1)dp[1] = height[i];else{for (j = i - 1; j >= 0; --j){if (dp[j] >= height[i] && dp[j + 1] < height[i]){dp[j + 1] = height[i]; mymax = max(mymax, j + 1);}}}}
4.其实感觉两个复杂度差不多┑( ̄Д  ̄)┍
最大子矩阵:
1. 最大子序列——以第i个数结束的子序列最大值=max(dp[i-1]+a[i],a[i])
2.增加一维
0 0
原创粉丝点击