一道基础性的动态规划题目,拿来练手,求最长不上升子序列和不上升子序列的最小划分数
代码有问题,测试数据:6,5,1,7,3,2
第一次动规的时候太贪了,6,5,3,2,导致第二问无法取得最优解,还要研究研究,不过过vijos的数据是没问题的。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int a[30]; int f[30]; int last[30]; int vis[30]; int n,end,total; int ans=0; void input() { int i=0; while(cin>>a[i]) { getchar(); i++; } n=i; end=n-1; total=n; } void work() { memset(last,-1,sizeof(last)); for(int i=0;i<n;i++) f[i]=1; for(int i=0;i<n-1;i++) for(int j=i+1;j<n;j++) { if(a[j]<a[i] && f[j]<f[i]+1 && vis[j]!=1 && vis[i]!=1) { f[j]=f[i]+1; last[j]=i; } } int max=0; //cout<<"work"<<endl; for(int i=0;i<n;i++) if(f[i]>=max && vis[i]!=1)//!!!!!!! >= > { //cout<<"max="<<max<<" f["<<i<<"]="<<f[i]<<endl; max=f[i]; end=i; } } int way() { int now=end; do { //cout<<a[now]<<" "; vis[now]=1; now=last[now]; total--; } while(now!=-1) ; //cout<<"total="<<total<<endl; //cout<<endl; if(total>0) return 1; else return 0; } int main() { memset(vis,-1,sizeof(vis)); input(); work(); cout<<f[end]<<","; while(way()) { work(); ans++; } cout<<ans<<endl; return 0; }