http://acm.sjtu.edu.cn/OnlineJudge/problem/4020
一上手就来了一个删点 排序+DFS.... 虽然正确性没问题 但是超时 只有60分. 主要在于不知道怎么减少搜索量
思路就是删除一些肯定不能在的点, 然后经过条件判断 DFS地去搜索最长的路径
#include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <stack> using namespace std; int n; int data[1000+10]; bool vis[1000+10]={false}; struct Point { int oriPos; int num; int todo; int vid; int done; int len; Point(int x,int y){ oriPos = x; num = y; todo = oriPos - num; vid = -1; done = 0; len = 0; } }; vector<Point> v; bool cmp_point(const Point& a , const Point& b){ return a.num < b.num; } void init(){ v.clear(); for (int i = 1; i <= n; ++i) { cin>>data[i]; if(data[i]<=i){ Point t(i,data[i]); v.push_back(t); } } sort(v.begin(),v.end(),cmp_point); memset(vis,false,sizeof(vis)); } //必须dfs int build(){ for (int i = 0; i < v.size(); ++i) { //cout<<v[i].oriPos<<","<<v[i].num<<","<<v[i].todo<<endl; v[i].vid = i; } int ans = 0; stack<Point> s; Point start(0,0); s.push(start); while(!s.empty()){ Point cur = s.top(); s.pop(); if(cur.vid >= 0) vis[cur.vid] = true; for (int j = cur.vid+1; j < v.size(); ++j) { if(cur.vid==-1 or (v[j].oriPos > v[cur.vid].oriPos and v[j].todo-cur.done >= 0 and v[j].num!=v[cur.vid].num)){ vis[j] = true; Point next(0,0); next.oriPos = v[j].oriPos; next.num = v[j].num; next.len = cur.len+1; next.done = v[j].todo; next.vid = j; ans = max(next.len,ans); s.push(next); } } } return ans; } int main(int argc, char const *argv[]) { while(cin>>n){ init(); cout<<build()<<endl; } return 0; }