UVA 10131

来源:互联网 发布:整站优化 百科 编辑:程序博客网 时间:2024/05/18 03:29

   题目大意是给定一个序列,每个元素有两项,要求找到最长的子序列,满足第一项递增,第二项递减,其实就是一个简单的DAG动态规划问题,我们将偏序关系定义为若i的第一项小于j的第一项,且i的第二项大于j的第二项,则i《j,那么此时构成DAG,找最长路径即可。

  状态的定义和状态转移方程不在多说,适当的总结一下,并不是一定要满足直观的大于小于才能构造DAG,对于一个问题,只要能抽象出偏序关系,即可尝试构造DAG。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;bool m[1010][1010]={false};int w[1010],iq[1010],size=1;int total[1010],path[1010];int dp(int i){if(total[i]!=-1) return total[i];int ans=-1,pos;for(int j=0;j<=size;j++) if(m[i][j]){int t=dp(j);if(ans<t) {ans=t;pos=j;}}total[i]=ans+1;path[i]=pos;return ans+1;}int main(){//freopen("in.txt","r",stdin);while(cin>>w[size]>>iq[size]) {m[size][0]=true;size++;}size--;memset(total,-1,sizeof(total));path[0]=total[0]=0;for(int i=1;i<=size;i++)for(int j=1;j<=size;j++) if(w[i]<w[j]&&iq[i]>iq[j])m[i][j]=true;int ans=0,pos;for(int i=1;i<=size;i++){int t=dp(i);if(t>ans) {ans=t;pos=i;}}cout<<ans<<endl;while(pos){cout<<pos<<endl;pos=path[pos];}return 0;}


 

0 0
原创粉丝点击