题目链接:UVa 10131 - Is Bigger Smarter?
LIS变形。讲解看这里。
先按重量递增排一下序。
然后用记忆化搜索或者递推都可以做。
记忆化搜索需要注意dp数组初值与非初值的区别。
还要注意排序后可能存在两个重量相同的排在一起,而题目要求的是重量严格递增。
两种方法用的时间差不多。
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; const int MAX_N = 1000 + 50; struct Ele { int w,s; int i; }; Ele ele[MAX_N]; int dp[MAX_N]; int lis; int cmp(const void *a, const void *b) { Ele *_a = (Ele*)a; Ele *_b = (Ele*)b; return (_a -> w) - (_b -> w); } void outputLIS(int index) { if(lis == 0) return; bool flag = false; if(dp[index] == lis) { flag = true; lis--; } outputLIS(index - 1); if(flag) cout << ele[index].i << endl; } int main() { char str[1024]; int num = 0; lis = 0; while(gets(str)) { if(!str[0]) break; sscanf(str,"%d%d",&ele[num].w,&ele[num].s); ele[num].i = num + 1; num++; } qsort(ele,num,sizeof(ele[0]),cmp); for(int i = 0;i < num;i++) { dp[i] = 1; for(int j = 0;j < i;j++) { if(ele[i].s < ele[j].s && ele[i].w != ele[j].w && dp[i] < dp[j] + 1) { dp[i] = dp[j] + 1; lis = max(lis,dp[i]); } } } cout << lis << endl; outputLIS(num - 1); return 0; }
#include <iostream> #include <stdio.h> #include <algorithm> #include <cstring> using namespace std; const int MAX_N = 1000 + 50; struct Ele { int w,s; int i; }; Ele ele[MAX_N]; int dp[MAX_N]; int lis,num; int cmp(const void *a, const void *b) { Ele *_a = (Ele*)a; Ele *_b = (Ele*)b; return (_a -> w) - (_b -> w); } int DP(int i) { if(dp[i] != 0) return dp[i]; dp[i] = 1; for(int j = i + 1;j < num;j++) { if(ele[i].s > ele[j].s && ele[i].w != ele[j].w) dp[i] = max(dp[i],DP(j) + 1); } return dp[i]; } void outputLIS(int index) { if(lis == 0) return; if(dp[index] == lis) { cout << ele[index].i << endl; lis--; } outputLIS(index + 1); } int main() { memset(dp,0,sizeof(dp)); char str[1024]; num = 0; lis = 0; while(gets(str)) { if(!str[0]) break; sscanf(str,"%d%d",&ele[num].w,&ele[num].s); ele[num].i = num + 1; num++; } qsort(ele,num,sizeof(ele[0]),cmp); for(int i = 0;i < num;i++) lis = max(lis,DP(i)); cout << lis << endl; outputLIS(0); return 0; }