冲刺noip10.08总结

刚从郑州回来,一周讲的内容跟海亮差不了多少,但是不知道为啥觉得思维更发散了,所有课件ppt什么的我都保存下来了,整理的东西都还在,收获也不小。

然后现在正式全面停课了,剩下一个月时间来冲刺noip,今天的题是不难,第一题很水,第二题看着很水,第三题看着很难。。

总算把代码更正完了,说说这次测试吧。

第一题就不说了吧,太简单了。


 

第二题,猛一看是个lis,仔细看又不一样,不能用lis,然后没有思路,就想打暴力,然后往后更新序列很简单,关键是往前更新序列,我想起了海亮的一道测试题,那题正解跟我的思路一样,具体记不清了,那个时候我弄成了往前更新的,不知道为啥,今天打出来以后不对,可能是两道题不一样吧,然后第二题就这样爆了0...正解是把这个不能用lis的序列变成能用lis的序列,然后再加一个二分优化就行了,会转化这个序列以后就很简单了,题目要求是严格上升的正整数子序列,遇到负的直接扔一边不管他叫就行了,等于又让我复习了一下二分优化lis

代码:

#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
inline int read()
{
int nnn=1,numm=0;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')nnn=-1;
ch=getchar();
}
while(isdigit(ch))
{
numm=(numm<<1)+(numm<<3)+ch-'0';
ch=getchar();
}
return nnn*numm;
}
int a[50005],n,f[50005],len;
int find(int x)
{
int l=1,r=len+1;
if(x<f[1]) return 0;
while(l+1<r)
{
int m=l+r>>1;
if(f[m]<=x) l=m;
else r=m;
}
return l;
}
int main()
{
//freopen("noname.in","r",stdin);
//freopen("noname.out","w",stdout);
register int t=read();
for(register int o=1;o<=t;++o)
{
n=read();
memset(f,10,sizeof(f));
for(register int i=1;i<=n;++i)
a[i]=read()-i;
len=0;
for(register int i=1;i<=n;++i)
{
if(a[i]<0) continue;
int id=find(a[i]);
len=max(id+1,len);
f[id+1]=min(f[id+1],a[i]);
}
printf("%d\n",n-len);
}
return 0;
}


 

第三题看着很难,除了一个全图最短路floyed其他没有一点头绪,然后我还是打了暴力,dfs三种情况,分别枚举三个点到目的地的情况,复杂度是O(3^L),然后我还有一个剪枝:if(sum>ans) return; 即使不加剪枝30分的数据是可以过的,是绝对可以过的,然而我有生以来第一次打错freopen,文件名是service,我不知道为啥在后头加了个s:services,可能是英语写多了吧,但是题目描述中的服务也不止一个啊。。。结果当然爆零了。。。。嗯第三题其实是个dp,你看我都想出了递归的分类情况,这不就是dp的转移方程吗?f[k][a][b][c],k表示执行到哪个任务,a、b、c分别表示三个点,考虑到三个点中肯定有一个在任务地点,由前面的k已知,所以可以省掉一维,所以最后的复杂度就是O(L*n^2)。想到dp这玩意我肯定能AC,但是我都知道怎么转移了啊。。。。

代码:

#include<cstdio>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
inline int read()
{
int nnn=1,numm=0;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')nnn=-1;
ch=getchar();
}
while(isdigit(ch))
{
numm=(numm<<1)+(numm<<3)+ch-'0';
ch=getchar();
}
return nnn*numm;
}
int w[201][201];
int f[501][201][201];
int x[505];
int main()
{

//freopen("service.in","r",stdin);
//freopen("service.out","w",stdout);
int o,n,l,ans;
o=read();
for(register int p=1;p<=o;++p)
{
n=read(),l=read();
ans=100000000;
memset(w,10,sizeof(w));
memset(f,10,sizeof(f));
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
w[i][j]=read();
for(register int i=1;i<=n;++i)
for(register int k=1;k<=n;++k)
for(register int j=1;j<=n;++j)
if(w[i][k]+w[k][j]<w[i][j]) w[i][j]=w[i][k]+w[k][j];
for(register int i=1;i<=l;++i)
x[i]=read();
f[0][1][2]=0;
x[0]=3;
for(register int k=1;k<=l;++k)
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
{
f[k][i][j]=min(f[k][i][j],f[k-1][i][j]+w[x[k-1]][x[k]]);
f[k][x[k-1]][j]=min(f[k][x[k-1]][j],f[k-1][i][j]+w[i][x[k]]);
f[k][i][x[k-1]]=min(f[k][i][x[k-1]],f[k-1][i][j]+w[j][x[k]]);
}
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
ans=min(ans,f[l][i][j]);
printf("%d\n",ans);
}
return 0;
}

调试第三题的时候一不小心粘成第二题的数据了,按说应该是还没输入完,我还纳闷为什么没有输出完呢,然后它自己又蹦出来了粘贴的最后一行数据,然后卡住了,不是不响应,而是关不掉,我把Dev关了不管用,Ctrl+C不管用,Alt+F4不管用(妈呀差点把正在编辑博客关了)

任务管理器也不管用,然后我在任务管理器的进程里找到了一个名称叫“services.exe”的正在运行的程序,(因为我freopen打错了,文件名打成了services,当时还没改过来)我也不知道是系统的程序还是我那个程序,反正我给他关了然后

然后检查代码,瞪了好长时间也没看出来哪里有问题,然后叫wy dalao帮我看看,然后我才发现数据粘错了。。。。dalao就是不一样

今天就到这里吧。。。

 

posted @ 2018-10-08 21:32  凉城听暖  阅读(110)  评论(0编辑  收藏  举报