1、一个人一天要完成工作,他把一天划分为n个单位时间,并告诉你他能够完成的m件事情 n<=5000 m<=5000
并给出这m件事情的开始时间、结束时间、能够获得的收益
进行工作的选取
struct node{ int end; int val; }temp[maxn]; int dp[maxn]; vector<node> vec[maxn]; //存储这个时间点开始的工作数 int n,m; int main(){ int s,e,op; scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d",&s,&e,&op); if(s<0||e>n) continue; //别忘了这一句话 vec[s].push_back((node){e,op}); //下标为起始时间,然后存入结束时间和收益 } node te; for(int i=0;i<n;i++){ for(int j=0;j<vec[i].size();j++){ te=vec[i][j]; dp[te.end]=max(dp[te.end],dp[i]+te.val); //计算从开始时间的最大收益 } dp[i+1]=max(dp[i+1],dp[i]); //做还是不做 } return 0; }
2、最长不下降子序列的优化算法
//最长不下降子序列 //第一种从前往后或者从后往前比较计算的时间复杂度时O(N^2) //另一种算法有O(Nlog2N) //利用有序队列优化,f[i]=max(f[j]+1),j<i且a[j]<=a[i],而且f[j]要尽可能地大!!! int n; int a[maxn]; //本事 int d[maxn]; //得到的结果序列 int pre[maxn]; //用来输出路径 int main(){ cin>>n; int len=1; for(int i=1;i<=n;i++) cin>>a[i]; d[1]=a[1];pre[1]=1; for(int i=2;i<=n;i++){ if(d[len]<=a[i]) { d[++len]=a[i];pre[i]=len; } else{ int j=upper_bound(d+1,d+1+len,a[i])-d; //返回第一个大于a[i]的坐标 d[j]=a[i]; //否则就找到位置替换掉 pre[i]=j; } } stack<int> st; for(int i=n,j=len;i>=1;i--){ if(pre[i]==j){ st.push(a[i]); --j; } if(j==0) break; } cout<<len<<endl; while(!st.empty()){ cout<<st.top()<<" "; st.pop(); } return 0; }
3、花店橱窗