题意繁琐, 不想写了......还是自己看题去吧...
最后我是简化为求一个DAG图的最长路径, 用dfs+剪枝+记忆化搜索dp来完成
本题一共有223个测试数据, 本来第222个test本地运行之后崩掉了...dfs的太深, 栈溢出了orz, 可是提交上oj之后却是AC. 果然LINUX博大精深我不懂啊233
有需要第222个test的或者是要所有数据的可以私信...
学长建议我用bfs+topo序做, 下次试试吧...一开始写了个bfs的也是本地崩了然后重写了dfs... 不知道之前的那个程序能不能过呢
这题光是读题就花了很久, 没有题解而且卡题的时候感觉整个人都不好了orz, 特别想砸电脑....不过这也是一种锻炼吧, 毕竟只是08年日本队伍冬合宿的某一天的题而已, 一想到他们每天都要做6题这个难度的我就觉得自己弱爆了....
看到四五年前的几个老怪物写的似乎都比我短而且内存占用少... 不过效率上的话这个还是最快的^_^
就内存问题而言, 第一次AC我烧了51+兆内存...在next数组那里我开了100...事实上如果用正确的建图方法, 只要开3就行了
这样内存占用一口气降到了8M, 必须吸取教训→_→
/*author: birdstorm*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <climits>
#define MAXN 1005
#define N 105
#define inf 1.0e20
#define eps 1.0e-10
#define MOD 1000000007
#define For(i,m,n) for(int i=(m);i<(n);i++)
#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)
#define rep(i,m,n) for(int i=(m);i<=(n);i++)
#define repd(i,m,n) for(int i=(m);i>=(n);i--)
#define LL long long
#define test
using namespace std;
int cs=0, n, m, k, a[N], prevnum, tot;
int cnt[MAXN], start[MAXN], dp[MAXN*N];
bool isok;
struct node{
int cntnext;
int hasprev;
int index;
int next[3];
};
node scale[N*MAXN];
int d(int i)
{
int &ans = dp[i];
if(ans > 0) return ans;
if(isok==false) return 0;
ans = 1;
for(int j = 0;j < scale[i].cntnext;j++){
ans=max(ans,d(scale[i].next[j])+1);
if(ans>n){
isok=false;
return 0;
}
}
return ans;
}
int main()
{
#ifndef test
//freopen("pianist_input.txt","r",stdin);
//freopen("AC_test.txt","r",stdin);
freopen("pianist.in","r",stdin);
freopen("pianist_output.txt","w",stdout);
#endif // test
while(scanf("%d%d",&n,&m),n||m){
tot=0; cs++;
int Max=0;
isok=true;
start[0]=0;
For(i,0,m){
scanf("%d",&cnt[i]);
int head=0;
bool c=true;
if(i) start[i]=start[i-1]+cnt[i-1];
For(j,0,cnt[i]) scanf("%d",&a[j]);
sort(a,a+cnt[i]);
For(j,0,cnt[i]){
scale[tot].index=a[j];
scale[tot].cntnext=0;
if(j) scale[tot].hasprev=1;
else scale[tot].hasprev=0;
if(j!=cnt[i]-1) scale[tot].next[scale[tot].cntnext++]=tot+1;
dp[tot]=-1;
tot++;
}
if(i){
int head1=0, head2=0;
while(head1<cnt[i-1]&&head2<cnt[i]){
int t1=start[i-1]+head1, t2=start[i]+head2;
int pt1=t1, pt2=t2;
while(scale[t1].index<scale[t2].index&&head1<cnt[i-1]) t1++,head1++;
if(t1!=pt1) scale[t1-1].next[scale[t1-1].cntnext++]=t2;
while(scale[t2].index<scale[t1].index&&head2<cnt[i]) t2++,head2++;
if(t2!=pt2) scale[t2-1].next[scale[t2-1].cntnext++]=t1;
}
}
}
//For(i,0,tot) {printf("%d: ",i); For(j,0,scale[i].cntnext) printf("%d ",scale[i].next[j]); puts("");}
For(i,0,m){
int t=start[i];
if(scale[t].hasprev==0) dp[t]=d(t), Max=max(Max,dp[t]);
if(isok==false) break;
}
if(Max>n||!isok) printf("Case %d: No\n",cs);
else printf("Case %d: Yes\n",cs);
}
return 0;
}
/*
6 2
3 2 4 7
3 3 6 8
5 2
3 2 4 7
3 3 6 8
8 8
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
7 8
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
13 10
1 512634628
6 1652933534 213546428 677347949 658345883 956908147 1031367795
3 2037809726 116667955 790987801
2 760105898 1094137029
5 1101583585 573358560 1598796630 561655915 1837702701
4 631617329 1253820193 488205827 186025101
2 458983056 969671259
3 1421327126 1482305888 228207250
4 1695852316 905555199 1585122896 505276815
5 1339721960 395602894 2053590949 2130709761 995386565
12 10
1 512634628
6 1652933534 213546428 677347949 658345883 956908147 1031367795
3 2037809726 116667955 790987801
2 760105898 1094137029
5 1101583585 573358560 1598796630 561655915 1837702701
4 631617329 1253820193 488205827 186025101
2 458983056 969671259
3 1421327126 1482305888 228207250
4 1695852316 905555199 1585122896 505276815
5 1339721960 395602894 2053590949 2130709761 995386565
0 0
*/