OUTLINE:
放苹果问题
拦截导弹问题
最大子矩阵
古代密码
//此题乃乱入的基础题,@@关键@@……读懂题意,字符频率一致即“YES”
Basic idea:
文件结构图:
1.抓住返回条件
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 & putout void 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; } }//while return; } 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; }//while if (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);//recursion dir_->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_plates scanf("%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]; else slv[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}
j
from 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.增加一维