【模拟试题1】【20150514】
简单写下自己的理解吧……
Pack
三种物品的背包:
1. $v(x)=A*x^2-B*x$ 价值随所分配的体积的变化而变化……
2. 多重背包
3. 完全背包
其实是个傻逼题,因为数据规模小,暴力就能过,然而由于没见过第一种物品的价值函数,加上题目描述不清楚,所以自己傻逼了(不知道怎么乱搞了一下,得了70分)
其实第一种物品就暴力枚举每一个物品我们分配给它多少空间就可以,“每个体积的甲类物品只有一个”TM就是在误导人!
不过倒是学习了一种新的写背包的姿势~
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //2015_05_14 pack 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<algorithm> 7 #define rep(i,n) for(int i=0;i<n;++i) 8 #define F(i,j,n) for(int i=j;i<=n;++i) 9 #define D(i,j,n) for(int i=j;i>=n;--i) 10 #define pb push_back 11 using namespace std; 12 typedef long long LL; 13 inline int getint(){ 14 int r=1,v=0; char ch=getchar(); 15 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 16 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 17 return r*v; 18 } 19 const int N=2010,M=2010; 20 /*******************template********************/ 21 int n,m,tot; 22 int num1,num2; 23 int A[N],B[N],v[N],c[N],w[N],v2[M],c2[M]; 24 int val[N][M]; 25 int f[N][M]; 26 27 void solve1(){ 28 F(i,1,num1) F(j,1,m) 29 val[i][j]=A[i]*j*j-B[i]*j; 30 F(i,1,num1) F(j,1,m) F(k,0,j) 31 f[i][j]=max(f[i][j],f[i-1][k]+val[i][j-k]); 32 F(j,1,m) f[0][j]=max(f[0][j],f[num1][j]); 33 /* F(k,0,m/2) F(i,1,num1) F(j,k+1,m-k) 34 f[i][k+j]=max(f[i][k+j],f[i-1][k]+val[i][j]);*/ 35 // F(i,1,num1) {F(j,1,m) printf("%d ",f[i][j]); puts("");} 36 F(j,1,m) F(i,1,num1) 37 f[0][j]=max(f[0][j],val[i][j]); 38 } 39 void solve2(){ 40 F(i,1,num2){ 41 int k=0; 42 while(w[i]>=(1<<k)){ 43 v2[++tot]=v[i]*(1<<k); 44 c2[tot]=c[i]*(1<<k); 45 w[i]-=1<<k; 46 k++; 47 } 48 if (w[i]){ 49 v2[++tot]=v[i]*w[i]; 50 c2[tot]=c[i]*w[i]; 51 } 52 } 53 // F(i,1,tot) printf("%d %d\n",v2[i],c2[i]); 54 F(i,1,tot) F(j,c2[i],m) 55 f[i][j]=max(f[i-1][j],f[i-1][j-c2[i]]+v2[i]); 56 // F(i,0,tot) {F(j,1,m) printf("%d ",f[i][j]); puts("");} 57 } 58 59 int main(){ 60 #ifndef ONLINE_JUDGE 61 freopen("pack.in","r",stdin); 62 freopen("pack.out","w",stdout); 63 #endif 64 n=getint(); m=getint(); 65 F(i,1,n){ 66 int x=getint(); 67 if (x==1){ 68 num1++; 69 A[num1]=getint(); 70 B[num1]=getint(); 71 }else if (x==2){ 72 num2++; 73 v[num2]=getint(); 74 c[num2]=getint(); 75 w[num2]=min(getint(),m/c[num2]); 76 }else{ 77 num2++; 78 v[num2]=getint(); 79 c[num2]=getint(); 80 w[num2]=m/c[num2]; 81 } 82 } 83 if (num1) solve1(); 84 solve2(); 85 printf("%d\n",f[tot][m]); 86 return 0; 87 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //2015_05_14 pack 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<algorithm> 7 #define rep(i,n) for(int i=0;i<n;++i) 8 #define F(i,j,n) for(int i=j;i<=n;++i) 9 #define D(i,j,n) for(int i=j;i>=n;--i) 10 #define pb push_back 11 using namespace std; 12 typedef long long LL; 13 inline int getint(){ 14 int r=1,v=0; char ch=getchar(); 15 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 16 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 17 return r*v; 18 } 19 const int N=1010,M=2010; 20 /*******************template********************/ 21 int n,m; 22 LL f[M]; 23 24 void solve1(int a,int b){ 25 D(j,m,1) F(i,0,j) 26 f[j]=max(f[j],f[j-i]+a*i*i-b*i); 27 } 28 void zeroone(int a,int b){ 29 D(j,m,b) 30 f[j]=max(f[j],f[j-b]+a); 31 } 32 void solve2(int a,int b,int c){ 33 int k=0; 34 while(c>=(1<<k)){ 35 zeroone(a*(1<<k),b*(1<<k)); 36 c-=(1<<k); 37 k++; 38 } 39 if (c) zeroone(a*c,b*c); 40 } 41 void solve3(int a,int b){ 42 F(j,b,m) 43 f[j]=max(f[j],f[j-b]+a); 44 } 45 int main(){ 46 #ifndef ONLINE_JUDGE 47 freopen("pack.in","r",stdin); 48 freopen("pack.out","w",stdout); 49 #endif 50 n=getint(); m=getint(); 51 F(i,1,n){ 52 int x=getint(), A=getint(), B=getint(),C; 53 if (x==1){ 54 solve1(A,B); 55 }else if (x==2){ 56 C=getint(); 57 solve2(A,B,C); 58 }else{ 59 solve3(A,B); 60 } 61 } 62 printf("%d\n",f[m]); 63 return 0; 64 }
Matrix
蛇形数阵啊……感觉好神的样子……然而并不会做……
花了半小时大概yy了一个模拟器出来,想打个表找找规律,结果规律没找到,突然发现这个模拟器是O(n)的,可以过60分的数据……那就大模拟跑暴力吧→_→
然而正解还是要找规律进行递推,在$\sqrt{n}$的时间内出解(回头补一下)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //2015_05_14 matrix 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 #define pb push_back 12 using namespace std; 13 typedef long long LL; 14 inline LL getint(){ 15 LL r=1,v=0; char ch=getchar(); 16 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 17 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 18 return r*v; 19 } 20 const int N=2010,mod=1e9+7; 21 /*******************template********************/ 22 LL n,m; 23 LL a[N][N],s[N][N],ans[N][N]; 24 LL tot; 25 void dfs2(int x,int y,int len); 26 void dfs3(int x,int y,int len); 27 void dfs4(int x,int y,int len); 28 void dfs1(int x,int y,int len){ 29 if (len>n) return; 30 rep(i,len-1) a[x][y+i]=++tot; 31 dfs2(x,y+len-1,len); 32 } 33 void dfs2(int x,int y,int len){ 34 if (len>n) return; 35 rep(i,len) a[x-i][y]=++tot; 36 dfs3(1,y+1,len+1); 37 } 38 void dfs3(int x,int y,int len){ 39 if (len>n) return; 40 rep(i,len-1) a[x+i][y]=++tot; 41 dfs4(x+len-1,y,len); 42 } 43 void dfs4(int x,int y,int len){ 44 if (len>n) return; 45 rep(i,len) a[x][y-i]=++tot; 46 dfs1(x+1,1,len+1); 47 } 48 49 void mak(){ 50 a[1][1]=1; a[1][2]=2; a[2][2]=3; a[2][1]=4; 51 tot=4; 52 dfs1(3,1,3); 53 // F(i,1,n){ F(j,1,n) printf("%3d",a[i][j]); puts("");} 54 F(i,1,n) F(j,1,n) s[i][j]=(s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]+mod)%mod; 55 // F(i,1,n){ F(j,1,n) printf("%5d",s[i][j]); puts("");} 56 F(i,1,n) F(j,1,n) ans[i][j]=(ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1]+s[i][j]+mod)%mod; 57 // F(i,1,n){ F(j,1,n) printf("%5d",ans[i][j]);puts("");} 58 } 59 60 int main(){ 61 #ifndef ONLINE_JUDGE 62 freopen("matrix.in","r",stdin); 63 freopen("matrix.out","w",stdout); 64 #endif 65 m=getint()%mod; 66 // cout <<m<<endl; 67 n=sqrt(m); 68 if (m-n*n>0) n++; 69 mak(); 70 F(i,1,n) F(j,1,n) if (a[i][j]==m){ 71 printf("%lld\n",ans[i][j]); 72 break; 73 } 74 return 0; 75 }
regexp
一看题目名字吓尿了,正则表达式!然而看完问题描述……shenmegui
其实一开始看题的时候只会做C题,tarjan缩点+dij跑最短路啊!开开心心码完,然而只有70分……因为是Windows评测,20W的点dfs需要用手工栈TAT不要这样好吗……不会手动栈啊……标程居然用了goto!我拒绝写!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //2015_05_14 regexp 2 #include<queue> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 #define pb push_back 12 using namespace std; 13 typedef long long LL; 14 inline int getint(){ 15 int r=1,v=0; char ch=getchar(); 16 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 17 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 18 return r*v; 19 } 20 const int N=200010,M=2e6+10; 21 /*******************template********************/ 22 int to[M],next[M],head[N],len[M],cnt; 23 void add(int x,int y,int z){ 24 to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt; len[cnt]=z; 25 } 26 int t[M],nxt[M],hd[N],l[M],cnt2; 27 void ins(int x,int y,int z){ 28 t[++cnt2]=y; nxt[cnt2]=hd[x]; hd[x]=cnt2; l[cnt2]=z; 29 } 30 31 int n,m; 32 int dfn[N],low[N],belong[N],st[N],top,dfs_clock,SCC; 33 bool in[N]; 34 void tarjan(int x){ 35 dfn[x]=low[x]=++dfs_clock; 36 st[++top]=x; 37 in[x]=1; 38 int y; 39 for(int i=head[x];i;i=next[i]) 40 if (!dfn[to[i]]){ 41 tarjan(to[i]); 42 low[x]=min(low[x],low[to[i]]); 43 }else if (in[to[i]]) low[x]=min(dfn[to[i]],low[x]); 44 if (dfn[x]==low[x]){ 45 SCC++; 46 do{ 47 y=st[top--]; 48 in[y]=0; 49 belong[y]=SCC; 50 }while(y!=x); 51 } 52 } 53 54 55 void rebuild(){ 56 F(x,1,n) for(int i=head[x];i;i=next[i]) 57 if (belong[x]!=belong[to[i]]) 58 ins(belong[x],belong[to[i]],len[i]); 59 } 60 struct node{int x,d;}; 61 bool operator < (const node &a,const node &b){return a.d>b.d;} 62 priority_queue<node>Q; 63 int d[N]; 64 bool vis[N]; 65 66 int dij(){ 67 memset(d,0x3f,sizeof d); 68 int S=belong[1],T=belong[n]; 69 d[S]=0; 70 Q.push((node){S,0}); 71 while(!Q.empty()){ 72 int x=Q.top().x; Q.pop(); 73 if (vis[x]) continue; 74 vis[x]=1; 75 for(int i=hd[x];i;i=nxt[i]) 76 if (d[t[i]]>d[x]+l[i]){ 77 d[t[i]]=d[x]+l[i]; 78 Q.push((node){t[i],d[t[i]]}); 79 } 80 } 81 return d[T]; 82 } 83 84 int main(){ 85 #ifndef ONLINE_JUDGE 86 freopen("regexp.in","r",stdin); 87 freopen("regexp.out","w",stdout); 88 #endif 89 n=getint(); m=getint(); 90 F(i,1,m){ 91 int x=getint(),y=getint(),z=getint(); 92 add(x,y,z); 93 } 94 tarjan(1); 95 // F(i,1,n) printf("belong[%d]=%d\n",i,belong[i]); 96 if (belong[1]==belong[n]) puts("0"); 97 else{ 98 rebuild(); 99 printf("%d\n",dij()); 100 } 101 return 0; 102 }
主要收获还是在背包问题上,确实没见过这种背包……感觉蛮新颖的,而标程中用函数的方式来处理每个物品的方法也是很棒的!新技能get√