前天做多校,做的很差,一直都是没怎么认真想题就去做或者就是感觉一看是树形dp就觉得很难,然后就没有认真去分析,心里感觉那样的题我肯定也写不出来,但是今天真的心平气和的做的时候发现也不难。。。。
想起来多校的第五场,有一道kmp的变形题,我分析了一半,然后和强神又分析了下,其实思路就和题解上是一样的了,但是却没有写:第一:感觉不好写,不知道怎么去写,写了也不一定可以写出来,第二:那题过的也就是那几个队,如果我们分析出来的话那些大牛学校也应该分析出来了,所以应该是错的吧,所以分析了那么多程序却是一个字都没有写的。比赛结束后我还在找这方面那方面的原因,最后强神说的一句话我觉得很好,就是没有自信,不敢去写,怕写错,不相信自己!!!!!
前天比赛,我做了第六题,不知道当时激动什么,连最基本的打表都忘了,想着那么多学校都过了,应该就可以暴力的,结果来了一个一点弯都没有拐的暴力,果断的TLE了,第四题的树形dp,也有点思路,但是没有深入去分析,一直觉得树形dp可难(心里作用),而且想着这些题钢牛是强项,也不用我去写,然后就没有然后了。。。第十题,最大二分匹配又加了点条件,想到的是建图然后求强连通分量,但是思路不怎么成熟,没有想到去虚拟王子和公主,然后就直接求联通分量了,然后就是自己找数据的时候发现了各种bug,然后一直WA,到最后就只想到了求强连通分量的思路可能是错的,没有进一步在此基础上去深入,贡献了无数的wa啊!第三题是博弈题,我一看了一眼图就让强神去看了,我的博弈真的是差,到现在都一道博弈题靠自己的力量写出来的都没有,然后强神奋战了几乎一下午,贡献了无数的RE和WA,也没有过,然后后来看了题解,他说他都分析出来了,只是什么与写错了。。。钢牛整场都在奋战第九题,方神回家了,然后整场比赛的结果,唉,说多了都是泪啊!
暑假过的好快,集训也快要结束了,然后感觉整个刷题的过程学东西可慢了,但是还是学会了不少,我感觉应该在比赛中多多总结经验,不然比赛因为一时失误将会做的题没做出来,那就亏大了啊!
今天将前天比赛的我集中分析的三道题写了一遍,感觉自己分析的思路总是差了那么一点点,然后就是过不去,我想什么时候给那个一点点给过去了,那应该是很大的提高吧! 还有一点就是平时训练的时候很懒散,算法想出来的时候但是写的时候总是晃晃悠悠的,没有一点时间观念,然后就导致比赛写题的时候敲代码花了好长时间,一定要改啊!
然后的然后,将我写的三道题代码贴出来好了,还有一道自己度错题WA了n次啊!!!!O_O
hdoj 4679
///////////////////////////////////////////////////////////////////////// // File Name: 4679.cpp // Author: wang // mail: // Created Time: 2013-8-17 14:55:24 ///////////////////////////////////////////////////////////////////////// #pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstdlib> #include <climits> #include <cstring> #include <cmath> #include <algorithm> #include<iostream> #include<queue> #include <map> using namespace std; typedef long long ll; #define INF (INT_MAX/10) #define SQR(x) ((x)*(x)) #define rep(i, n) for (int i=0; i<(n); ++i) #define repf(i, a, b) for (int i=(a); i<=(b); ++i) #define repd(i, a, b) for (int i=(a); i>=(b); --i) #define clr(ar,val) memset(ar, val, sizeof(ar)) #define N 210000 int h[N],f[N];//h[y]指的是子树中的最大直径的 int pre[N]; int n,len; int dis[N]; int Max,sign; struct node{ int y,w,pre,sign; }; node a[N]; int fir[N][3]; int firp[N][3];//最大,次大和次大大 void init() { memset(pre,-1,sizeof(pre)); len=1; memset(h,0,sizeof(h)); memset(f,0,sizeof(f)); memset(fir,0,sizeof(fir)); memset(firp,-1,sizeof(firp)); memset(dis,0,sizeof(dis)); } void addpage(int x,int y,int w,int z) { a[len].sign=z; a[len].y=y; a[len].w=w; a[len].pre=pre[x]; pre[x]=len++; } void dfs(int x,int fa)//最大的肯定得有的 { for(int i=pre[x]; i!=-1; i=a[i].pre) { int y=a[i].y; if(y==fa) continue; dfs(y,x); //从上面下来的 rep(j,3)//更新的 if(fir[y][0]+a[i].w>fir[x][j]) { repd(k,2,j+1)//-1也是这样传递的 fir[x][k]=fir[x][k-1], firp[x][k]=firp[x][k-1]; fir[x][j]=fir[y][0]+1;//y的最大的子跟+1; firp[x][j]=y; break; } } h[x]=fir[x][0]+fir[x][1];//指的是最大的 } void ddfs(int x,int fa) { //fa的dis怎么维护的???? for(int i=pre[x]; i!=-1; i=a[i].pre) { int y=a[i].y;//删除以y为跟的子树的 if(y==fa) continue; int m=0; rep(j,3)//x子树中另外的最大的, { if(firp[x][j]!=y) { f[y]+=fir[x][j],m++; dis[y]=max(dis[y],fir[x][j]+1);//求出y以上的最大值的 } if(m==2) break; } dis[y]=max(dis[y],dis[x]+1);//有可能是上面的承接下来的 rep(j,3) if(firp[x][j]!=y) { f[y]=max(f[y],fir[x][j]+dis[x]); break; } //x中的最大的 f[y]=max(f[y],f[x]);//去掉x时的最大的 for(int k=pre[x]; k!=-1; k=a[k].pre)//x的其它子节点中的最大的 { if(a[k].y!=fa && a[k].y!=y) { f[y]=max(f[y],h[a[k].y]);//兄弟子树中的最大值的 } } ddfs(y,x); } } void ans(int x,int fa) { for(int i=pre[x]; i!=-1; i=a[i].pre) { int y=a[i].y; if(y==fa) continue; int m=a[i].w*max(h[y],f[y]); if(m<Max) { Max=m; sign=a[i].sign; } else if(m==Max && a[i].sign<sign) sign=a[i].sign; ans(y,x); } } int main() { int test; scanf("%d",&test); int x,y,z; repf(ror,1,test) { init(); scanf("%d",&n); rep(i,n-1) { scanf("%d%d%d",&x,&y,&z); addpage(x,y,z,i+1); addpage(y,x,z,i+1); } dfs(1,-1);//求出x为跟的子树中的最大的直径的 //去掉以x为跟的子树后的最大直径f[N]; f[1]=0; dis[1]=0; ddfs(1,-1);//默认1为整棵树的跟的 // repf(i,1,n) cout<<h[i]<<" "; cout<<endl; // repf(i,1,n) cout<<f[i]<<" "; cout<<endl; // repf(i,1,n) cout<<dis[i]<<" "; cout<<endl; Max=INT_MAX; ans(1,-1); printf("Case #%d: %d\n",ror,sign); } return 0; }
///////////////////////////////////////////////////////////////////////// // File Name: t.cpp // Author: wang // mail: // Created Time: 2013-8-15 12:38:36 ///////////////////////////////////////////////////////////////////////// #include <cstdio> #include <cstdlib> #include <climits> #include <cstring> #include <cmath> #include <algorithm> #include<iostream> #include<queue> #include <map> using namespace std; typedef long long ll; #define INF (INT_MAX/10) #define SQR(x) ((x)*(x)) #define rep(i, n) for (int i=0; i<(n); ++i) #define repf(i, a, b) for (int i=(a); i<=(b); ++i) #define repd(i, a, b) for (int i=(a); i>=(b); --i) #define clr(ar,val) memset(ar, val, sizeof(ar)) #define N 1010 char a[N],b[N],c[N]; int dp[N][N]; int dp2[N][N]; int n,m; struct node{ int l,r; }; node aa[N*10],bb[N*10]; void fun() { n=0; int lena=strlen(a),len=strlen(c); rep(i,lena) { if(a[i]==c[0]) { aa[n].l=i; int k=0; repf(j,i,lena-1) { if(a[j]==c[k]) { k++; if(k==len) { aa[n++].r=j; break; } } } } } return ; } void fun1() { m=0; int lenb=strlen(b),len=strlen(c); rep(i,lenb) { if(b[i]==c[0]) { bb[m].l=i; int k=0; repf(j,i,lenb-1) { if(b[j]==c[k]) { k++; if(k==len) { bb[m++].r=j; break; } } } } } return ; } void work() { memset(dp,0,sizeof(dp)); int lena=strlen(a),lenb=strlen(b); rep(i,lena) rep(j,lenb) if(a[i]==b[j]) dp[i+1][j+1]=max(dp[i][j]+1,max(dp[i+1][j],dp[i][j+1])); else dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]); // rep(i,lena+1){ // rep(j,lenb+1) // cout<<dp[i][j]<<" "; cout<<endl;}cout<<endl; memset(dp2,0,sizeof(dp2)); repd(i,lena-1,0) repd(j,lenb-1,0) if(a[i]==b[j]) dp2[i][j]=dp2[i+1][j+1]+1; else dp2[i][j]=max(dp2[i+1][j],dp2[i][j+1]); // repd(i,lena-1,0){ // repd(j,lenb-1,0) // cout<<dp2[i][j]<<" "; cout<<endl;} } int main() { int test; scanf("%d",&test); getchar(); repf(ror,1,test) { // scanf("%s%s%s",a,b,c); gets(a); gets(b); gets(c); fun(); fun1(); int Max=0; work(); int lena=strlen(a); int lenb=strlen(b); // cout<<n<<" "<<m<<endl; rep(i,n) rep(j,m) { // cout<<aa[i].l<<" "<<aa[i].r<<" "<<bb[j].l<<" "<<bb[j].r<<endl; // cout<<dp[aa[i].l][bb[j].l]<<" "<<dp[lena][lenb]<<" "<<dp[aa[i].r+1][bb[j].r+1]<<endl; Max=max(Max,dp[aa[i].l][bb[j].l]+dp2[aa[i].r+1][bb[j].r+1]); } printf("Case #%d: %d\n",ror,Max+strlen(c)); } return 0; }1010Prince and Princess
/////////////////////////////////////////////////////////////////////////
// File Name: 4685.cpp
// Author: wang
// mail:
// Created Time: 2013-8-17 10:18:33
/////////////////////////////////////////////////////////////////////////
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<iostream>
#include<queue>
#include <map>
using namespace std;
typedef long long ll;
#define INF (INT_MAX/10)
#define SQR(x) ((x)*(x))
#define rep(i, n) for (int i=0; i<(n); ++i)
#define repf(i, a, b) for (int i=(a); i<=(b); ++i)
#define repd(i, a, b) for (int i=(a); i>=(b); --i)
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define N 2005//增加公主或者王子的饿个数可以很大的
int n,m;
bool vis[N];
int ans[N];
class ring{
public:
int len,tot,ror,col;
int dfn[N],low[N],pre[N];
int stage[N];
bool mark[N];
int Stack[N];
struct node{
int y,pre;
};
node a[N*1001];
void init()
{
len=1; col=0; tot=1; ror=1;
memset(dfn,0,sizeof(dfn));
memset(pre,-1,sizeof(pre));
memset(mark,false,sizeof(mark));
memset(stage,0,sizeof(stage));
}
void addpage(int s,int t)
{
// cout<<s<<" "<<t<<endl;
a[len].y=t;
a[len].pre=pre[s];
pre[s]=len++;
}
void dfs(int x)
{
Stack[ror++]=x;
dfn[x]=low[x]=tot++;
mark[x]=true;
for(int i=pre[x]; i!=-1; i=a[i].pre)
{
int y=a[i].y;
if(!dfn[y])
{
dfs(y);
low[x]=min(low[x],low[y]);
}else if(mark[y]==true)
low[x]=min(low[x],dfn[y]);
}
int i;
if(dfn[x]==low[x])
{
++col;
do{
i=Stack[--ror];
mark[i]=false;
stage[i]=col;
}while(i!=x);
}
}
};
ring ri;
class match{
public:
vector<int>vec[N];
bool vis[N];
int n,k;
int next[N];
void init()
{
rep(i,N) vec[i].clear();//清空的
memset(next,-1,sizeof(next));
}
bool find(int t)
{
rep(i,vec[t].size())
{
int m=vec[t][i];
if(vis[m]==false)
{
vis[m]=true;
if(next[m]==-1 || find(next[m]))
{
next[m]=t;
return true;
}
}
}
return false;
}
int sum()//求的是最大匹配数的
{
int m=0;
rep(i,n)
{
memset(vis,false,sizeof(vis));
if(find(i))
m++;
}
return m;
}
};
match ma;
void solve()
{
int l,x;
ma.n=n;
ma.init();
rep(i,n)
{
scanf("%d",&l);
while(l--)
scanf("%d",&x),ma.vec[i].push_back(x-1);//减去1的
}
ma.sum();//最大匹配的
memset(vis,false,sizeof(vis));
rep(i,m)//m个公主的
if(ma.next[i]==-1)//没有匹配的
{//增加一个王子的
ma.next[i]=n;
// ma.vec[n].clear();//增加之前先清空的
rep(j,m) ma.vec[n].push_back(j);//王子喜爱每一位公主的
vis[n]=true;
n++;
}
else vis[ma.next[i]]=true;
rep(i,n)
if(vis[i]==false)//该王子没有被匹配的
{//增加一位公主的
ma.next[m]=i;//增加一位公主的
rep(j,n) ma.vec[j].push_back(m);//每位王子都爱这个公主的
m++;
}
}
void work()
{
ri.init();
rep(i,n)
rep(j,ma.vec[i].size())
ri.addpage(i,ma.vec[i][j]+n);//加边的
rep(i,m)
ri.addpage(i+n,ma.next[i]);
rep(i,n+m)
if(ri.dfn[i]==0) ri.dfs(i);//求强连通的
}
int main()
{
int test;
scanf("%d",&test);
int nn,mm;
repf(ror,1,test)
{
scanf("%d%d",&n,&m);
nn=n; mm=m;
solve();//最大匹配并进行添加的
work();//求强连通分量的额
// rep(i,n+m) cout<<ri.stage[i]<<endl;
printf("Case #%d:\n",ror);
rep(i,nn)
{
ans[0]=0;
for(int j=ri.pre[i]; j!=-1; j=ri.a[j].pre)//可以匹配的
{
int y=ri.a[j].y-n;
if(y<mm && ri.stage[i]==ri.stage[y+n])
ans[++ans[0]]=y;
}
printf("%d",ans[0]);
sort(ans+1,ans+1+ans[0]);
repf(j,1,ans[0])
printf(" %d",ans[j]+1);
printf("\n");
}
}
return 0;
}