吐槽分析:
最长递增递减子序列(动态规划)
index从1开始 ms()只要到 m+i就可以了 不要到 m+i+1 坑爹啊
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define ms(x, y) memset(x, y, sizeof(x))
const double PI = acos(-1.0), eps = 1e-8;
struct mice {
int w,s,index;
}m[1010];
int dp[1010],pre[1010],ans[1010];
// 按体重升序 其次按速度降序
bool cmp(mice a,mice b) {
if(a.w == b.w)
return a.s > b.s;
return a.w < b.w;
}
int main() {
int i=1,j,k;
// test();
while(scanf("%d%d",&m[i].w,&m[i].s) != EOF) {
m[i].index = i;
i++;
}
// 按规则排序 m+i 就可以了!! 不用m+i+1
sort(m+1, m+i, cmp);
ms(pre,0);
// ms(dp,1) 是不可以的! 1不行
for(j=1; j<i; j++)
dp[j] = 1;
// 从按体重升序排列的序列中取得按速度的最长下降子序列
// “人人为我型 ” 动态规划
for(j=2; j<i; j++) { // 遍历终点
for(k=1; k<j; k++) {
if(m[k].w < m[j].w && m[k].s > m[j].s
&& dp[k]+1 > dp[j]) {
dp[j] = dp[k] + 1;
pre[j] = k; // 每个点都记录它前面那个点
}
}
}
// printf("%d\n",*max_element(dp+1, dp+i+1));
int maxLen = 0;
int maxInd;
for(j=2; j<i; j++) {
if(dp[j] > maxLen) {
maxLen = dp[j];
maxInd = j;
}
}
// printf("%d %d\n",maxInd,maxLen);
// 找到最长情况 且此最长序列的终点 index = maxInd
int t = maxInd;
j=0;
while(t!=0) {
ans[j++] = t; // 从最终的坐标记忆追溯之前的index
t = pre[t];
}
printf("%d\n",maxLen);
while(j > 0) {
j--;
printf("%d\n",m[ans[j]].index);
}
return 0;
}