03 2013 档案
摘要:还是思维不够灵活,刚开始,只想到了那个O(n3)的算法,知道肯定不行,苦苦思索,实在想不出来,浏览了一下其他人的博客,刚扫一眼,突然想到了还是从最优解的最后的状态考虑,得到了O(n2)的算法,就是对于节点i,枚举,在他左边的与他举例小于l3的点,得到状态转移方程f[i]=min(f[j]+cost),ac之,然后看了浩神的博客,还可以用二分优化,想了想,确实可以,因为点到s起点的举例是单调非减的,对于同一段的肯定最左边的最优,二分得之#include <iostream>
#include <cstdio>
#define LL __int64
#define min(
阅读全文
摘要:dp+线段树,dp是核心,线段树用来优化复杂度,dp过程好像,但是要确定从一个fence边缘向下沿直线走,下一个fence是哪个,最朴素的想法就是从上到下扫描,时间为O(n2),数据量比较大,可能会超时。然后用线段树来优化这个过程,当输入第i个fence的左右点时,1~i-1的fence所覆盖区间已插入到了线段树中(并在所覆盖的区间发记录fence编号)那么此时,求fence(i)的左点l向下会走到哪个fence,可以从线段树的根开始搜索,搜索到l的这条路径上的最大编号,也就是覆盖了点l的区间上的最大编号,从而得到所求编号#include <iostream>
#include &
阅读全文
摘要:树形DP,f(i,j)表示i节点及其子树得到j个国家所需的最小贿赂,对于j==i子树的节点总数sum,所需的最小费用肯定就是i节点本身的cost,对于j<sum的情况,肯定只有在其子树中选,如果选了i就是把整个子树都选了,然后,这个过程用的是01背包的思想,不知道这个词用的 恰不恰当,但想清楚,这个DP过程就可以了,对每个i的子树,恩。//思路来啦
#include <iostream>
#include <cstdio>
#include <cstring>
#define mem(a,b) memset(a,b,sizeof(a))
#define
阅读全文
摘要:状态压缩,看了周伟的动态规划之状态压缩,讲解的很详细,从写程序,到ac花了7个小时,3个小时敲代码,并理思路,4个小时调错,最后发现还是粗心问题,算法上病没有错误,不能在等啦,以后wa后,先仔细把代码看一遍,要有耐心呢,不能过度依赖调试,可能后者会浪费更多的时间#include <iostream>
#include <cstdio>
#include <string.h>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
char g[100+10][10+10];
int c[65];
阅读全文
摘要:典型的二位费用背包问题,主要是边界的考虑#include <iostream>
#include <cstdio>
#include <cstring>
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b)) using namespace std;
const int inf=0x3f3f3f3f;
int f[100+10][1000+10];
int w[100+10],v[100+10];
int main()
{ int t; cin>>t
阅读全文
摘要:这道题虽然是道YY题,就两行代码,但挺锻炼思维的#include <iostream>
#include <cstdio>
using namespace std;
int main()
{ int n; while(cin>>n&&n) { if(n%2==0) cout<<"No Solution!"<<endl; else cout<<n-1<<endl; } return 0;
}
阅读全文
摘要:dp之,状态转移方程比较好理解。学到的东西就是可以通过拓展状态的维数,是思路更加简便,严谨#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1500+10;
int head[maxn][15],d[maxn];
int f[maxn][2];
int n;
int min(int a,int b) { return a<b?a:b; } void dp(int x)
{ if(d[x]==0) { f[x][0]=0; f[x][1]=1; return; } fo
阅读全文
摘要:从最优解的结果考虑,f(s)表示节点集合s最多可分为多少组,如果s中节点及其所连节点的并集是节点的全集的话说明s至少可分为一组,反之,可知f(s)=0,当确定s至少可分一组时,可知其最优解的组成肯定是s的某一子集s0(s0中各节点及其联接的节点的并集为全集且s0只能分成一组否则会造成浪费)+(s-s0),那么f(s)=max{f(s-s0)+1.#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=20;
int n;
int p[maxn];
int f[1<<m
阅读全文
摘要:完全背包问题的变形,79ms,不过此题需要一个优化,就是把背包实际容量除以1000,不优化的话,数据量很大,会超时。刚开始优化直接定义成double,除了之后再乘,wa,因为有浮点误差,后来考虑了一下,改为了int,ac#include <iostream>
#include <cstdio>
using namespace std;
int amount;
int d,year;
int intere[11];
int v[11];
int f[100000];
int main()
{ int N; cin>>N; while(N--) { cin>
阅读全文
摘要:解题思路看了官方的思路,就是前缀和的思想,做题时也想到了用前缀和,但没想到怎么才能提高效率,一点一点进步吧做完后,各种失误,各种wa,经过n个时间的查错,终于ac啦#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=100000+3;
int s[maxn][35];
int a[maxn][35];
int head[maxn],nexvt[maxn];
int n,k;
int main()
{ while(~scanf("%d%d",&n,&
阅读全文
摘要:又是LIS,又没看出来,写了一个O(n2),用滚动数组优化的算法,超时,瞥了一眼discuss看到了LIS这个字眼,一想,还果然可转化为LIS,而且还这么明显,居然没看出来#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int maxn=40000+10;const int inf=200000000;int num[maxn];int f[maxn],d[maxn];int main(){ int n,p; scanf("%d&qu
阅读全文
摘要:无限感慨啊,这道题半年前就做过,无限wa就放弃了,今天又重做这题,依旧没变无限wa,只不过这次敲了20分钟就完了,代码也简洁了,哈希函数直接自己构造的,比之前熟练了,然后检查,历经一个小时之后,才发现把'eh'当成了'en',改后ac,300ms,然后再翻出之前的代码,果然是同样的错误,回想起半年前的那一整个下午,真是欲哭无泪啊#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn=100000+3;int
阅读全文
摘要:dp状态转移方程:d(i,j)=sum(i,j)-min{d(i+1,j),d(i+2,j)...d(j,j),d(i,j-1),d(i,j-2)...d(i,i),0}可化为d(i,j)=sum(i,j)-min{f(i+1,j),g(i,j-1),0}#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int maxn=100+10;int arr[maxn];int f[maxn][maxn],d[maxn][maxn],s[maxn],g[ma
阅读全文
摘要:递推,把问题转化为具有相同问题的子问题,通过子问题最后所剩余的编号,退出此问题所剩余的编号#include <iostream>
using namespace std;
const int maxn=10000+10;
int f[maxn];
int main()
{ int n,k,m; while(~scanf("%d %d %d",&n,&k,&m)) { if(!n&&!k&&!m) break; f[1]=0; for(int i=2;i<=(n-1);i++) f[i]=(f[i-1]
阅读全文
摘要:最短路的应用,只不过路径的权值从单一的长度变成了各种耗费时间的和#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn=300+10;
const int maxm=(50000+10)*2;
const int inf=200000000;
int head[maxn],dis[maxn],vis[maxn],pre[maxn],re[maxn],ans[maxn];
int e[maxm],nextv[maxm],cost[
阅读全文
摘要:比较水的题,但是要细心,把情况考虑清楚#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=10000;
const double eps=1e-8;
int n,f[maxn];
double rad;
struct Point
{ double x,y;
};
Point ver[maxn],pel;
double cross(Point a,Point b,Point c,Point d)
{ return (b.x-a.x
阅读全文
摘要:复习了下线段树线段树的区间修改这道题有调试了两个多小时,怎么没进步啊,wa的原因是两个int形相乘,结果如果是long形,不仅结果的变量要用long,这两个数也得是long形,不然仍会溢出,原来就犯过同样的错误,怎么又犯了,还有找了那么长时间,k靠!!!!!!!!!!!!还有还有,如果要组成if else 语句,要有括号就都有,不能只有一个有#include <iostream>
#include <cstdio>
#include <algorithm>
#define LL __int64
using namespace std;
int n,tot;
阅读全文
摘要:计算几何凸包,理解的不是很透彻,还是为什么要用凸包而不是一般的凸多边形这一问题,代码的准确率还是很低,以后要仔细仔细再仔细#include <iostream>#include <stdio.h>#include <algorithm>using namespace std;const int maxn=1000+10;struct Point{ int x,y;};Point po[maxn];int vis[maxn];int n;int cou[maxn];int ch[maxn];int cross(Point a,Point b,Point c,P
阅读全文
摘要:直线的交点,题目不是很难,但还是太粗心,其中有一步疏忽,导致无限wa,最后还是发现了#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=10000;
double eps=1e-10;
struct node
{ double x1,x2,y;
};
struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y) {};
};
node arc[maxn
阅读全文
摘要:凸包至今还不知道这道题为什么凸包就是解,在网上搜结题报告也都是说求凸包,没告诉深层原因,求大神解答#include <iostream>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;
const int maxn=1000+10;
struct node
{ int x,y;
};
node point[maxn];
int ch[maxn];
int n,l;
bool cmp(node a,node b)
{ if(a.x<b.
阅读全文
摘要:哎~~~~~~~~~~~~#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
const int maxn=25*2;
const double eps=1e-8;
struct Point
{ double x,y;
};
int n;
double maxv;
Point up[maxn],bottom[maxn];
struct Line{ double a, b, c;
};
double cross(Point a,Point b,Point c
阅读全文
摘要:贪心+计算几何(叉点积)个人认为本体用贪心解释最合理,我就是用贪心思考的此题代码些的太挫啦#include <iostream>#include <stdio.h>#include <stack>#include <math.h>#include <string.h> using namespace std;const int maxn=55;int m,n;int vis[maxn];int path[maxn];struct Point{ int x,y; Point(int x=0,int y=0):x(x),y(y) { }}
阅读全文
摘要:题目不难,就是线段相交判断。叉积和点积的应用,但是却需要细心,看清题意#include <iostream>#include <stdio.h>using namespace std;int cross(int x1,int y1,int x2,int y2){ return x1*y2-y1*x2;}int dot(int x1,int y1,int x2,int y2){ return x1*x2+y1*y2;}int ons(int x1,int y1,int x2,int y2,int x3,int y3){ if(cross(x3-x1,y3-y1,x3-x2
阅读全文
摘要:这道题学会的就是从结果想问题,找到应该考虑的方向如果存在一直线l,使所有线段在l上的投影有交点,考虑只有一个交点这个极限,过此交点m做l的垂线,所有线段上的那个在l上的投影是m的点肯定过此垂线,所以存在直线l的必要条件就是至少存在一条直线交所有的线段,然后很显然至少存在一条直线交所有的线段是存在直线l的充分条件,所以原问题就转化为了是否有一条直线交所有的线段,而这一问题,可转换为是否存在过某两条线段的某两个不重合的端点的直线,交所有的线段。但太粗心了,这道题经该了4个小时,才把所有错误改完啦,ai~~~~~~~~~~~#include <iostream>
#include <
阅读全文
摘要:这道题目思维+基础,好题目拓扑排序以后看到sij就要想到连续和转化为前缀和之差的思想,通过表格得到两两前缀和的大小关系,然后通过拓扑排序得到前缀和的大小序列,确定每个前缀和的大小,最后得到结果#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn=11;
int e[maxn][maxn],b[maxn],in[maxn],sol[maxn];
int n,loc;
void topo()//基于栈的topo排序
{ int i
阅读全文

浙公网安备 33010602011771号