#include using namespace std; const int N = 55; const int INF = 0x3f3f3f3f; int n; int a[N]; int up[N], down[N]; int res; // 本题关键字:贪心+爆搜 /* 功能:暴搜所有可能,配合剪枝,找出最少的拦截系统数量 u: 第几个导弹 ul: 上升拦截系统的数量,配合up 数组使用 dl: 下降拦截系统的数量,配合down数组使用 */ void dfs(int u, int ul, int dl) { if (ul + dl >= res) return; // 伟大的剪枝,不剪枝会TLE~,中途发现已经大于等于res的情况,就返回 if (u == n) { // 走完全程,收集答案 res = ul + dl; // 因为上面的剪枝,把ul+dl>=res的全干掉了,能到这里的,都是= a[u]) break; t = down[k]; // 保留现场 down[k] = a[u]; if (k < dl) dfs(u + 1, ul, dl); else dfs(u + 1, ul, dl + 1); down[k] = t; // 回溯 } int main() { while (cin >> n, n) { // 多套数据,输入n=0时停止 for (int i = 0; i < n; i++) cin >> a[i]; res = INF; // 防御系统的最少数量 dfs(0, 0, 0); // 开始深搜,更新res的值 printf("%d\n", res); } return 0; }