标签:
No 1. 生活大爆炸版石头剪刀布
http://www.luogu.org/problem/show?pid=1328
这是道大水题,我都在想怎么会有人错了,没算法,直接模拟,别读错题.
1 int wn[5][5]={{2,0,1,1,0}, 2 {1,2,0,1,0}, 3 {0,1,2,0,1}, 4 {0,0,1,2,1}, 5 {1,1,0,0,2}}; 6 7 int n,na,nb; 8 int a[222],b[222]; 9 int s1,s2; 10 11 int main() 12 { 13 ios_base::sync_with_stdio(0); 14 15 cin>>n>>na>>nb; 16 17 for(int i=1;i<=na;i++) 18 { 19 cin>>a[i]; 20 } 21 22 for(int i=1;i<=nb;i++) 23 { 24 cin>>b[i]; 25 } 26 27 int f1=0,f2=0; 28 29 for(int i=1;i<=n;i++) 30 { 31 f1++; 32 f2++; 33 if(f1>na) f1=1; 34 if(f2>nb) f2=1; 35 if(wn[a[f1]][b[f2]]==1) s1++; 36 else if(wn[a[f1]][b[f2]]==0) s2++; 37 } 38 39 cout<<s1<<‘ ‘<<s2<<endl; 40 41 return 0; 42 }
No 2. 联合权值
http://www.luogu.org/problem/show?pid=1351
同样是水题,用加法结合律.
首先,距离为2的两点,必有一个节点与他们都相连.
第一个要求最大值,对于每个点,预处理出相邻的边中权值最大的两条边,枚举每个点,计算这两个值的乘积,求个最大值即可.
第二个,要求距离为2的点对的权值之和,那么,我们先确定某点对中间的那个点,设为p,并预处理出p与其相邻的点距离之和d,则与其相邻的某点q,在中心点为p的距离为二的一条路径上的权值之和为d(q,p)*d(m1,p)+d(q,p)*d(m2,p)+...+d(q,p)*d(mi,p)=d(q,p)*(d-d(q,p)) 其中mi为与p相邻的除q以外的点,共i个.
最后求和即可.
1 long long n; 2 const long long MOD=10007; 3 long long w[222222]; 4 long long sum[222222]; 5 long long mx; 6 long long ans; 7 vector<long long> e[222222]; 8 long long m1[222222],m2[222222]; 9 10 int main() 11 { 12 scanf("%lld",&n); 13 14 for(long long i=1;i<n;i++) 15 { 16 long long a,b; 17 scanf("%lld %lld",&a,&b); 18 e[a].pb(b); 19 e[b].pb(a); 20 } 21 22 for(long long i=1;i<=n;i++) 23 { 24 scanf("%lld",&w[i]); 25 } 26 27 for(long long i=1;i<=n;i++) 28 { 29 for(long long j=0;j<(long long)e[i].size();j++) 30 { 31 sum[i]+=w[e[i][j]]%MOD; 32 33 if(w[e[i][j]]>m1[i]) 34 { 35 m2[i]=m1[i]; 36 m1[i]=w[e[i][j]]; 37 } 38 else if(w[e[i][j]]>m2[i]) 39 { 40 m2[i]=w[e[i][j]]; 41 } 42 } 43 } 44 45 for(long long i=1;i<=n;i++) 46 { 47 mx=max(mx,m1[i]*m2[i]); 48 } 49 50 printf("%lld ",mx); 51 52 for(long long i=1;i<=n;i++) 53 { 54 for(long long j=0;j<(long long)e[i].size();j++) 55 { 56 ans=ans+(w[e[i][j]])*(sum[i]-w[e[i][j]]); 57 ans=ans%MOD; 58 } 59 } 60 61 printf("%lld\n",ans); 62 63 return 0; 64 }
No 3. 飞扬的小鸟
http://www.luogu.org/problem/show?pid=1941
dp
dp
dp
其实这题真心不难
不明白为何有许多人不会做........
我们用dp(i,j)表示鸟儿飞到第i根柱子的j高度处所用的最少跳跃步数.
Obviously,不跳,摔落比较好,所以先处理它.
明显的,dp[i+1][j-y[i]]=min(dp[i+1][j-y[i]],dp[i][j]).
当鸟儿跳的时候,要是到顶了不能继续跳,所以要分个类:
1.到顶了
dp[i][m]=min(dp[i][m],dp[i][j]+1)
dp[i+1][m]=min(dp[i+1][m],dp[i][j]+1)
2.没到顶
dp[i][j+x[i]]=min(dp[i][j+x[i]],dp[i][j]+1);
dp[i+1][j+x[i]]=min(dp[i+1][j+x[i]],dp[i][j]+1);
于是就可以写程序了...
1 int dp[11111][1111]; 2 int l[11111],r[11111]; 3 int has[11111]; 4 int x[11111],y[11111]; 5 int ans; 6 int n,m,k; 7 8 int main() 9 { 10 ios_base::sync_with_stdio(0); 11 12 cin>>n>>m>>k; 13 14 for(int i=0;i<11111;i++) 15 { 16 l[i]=1; 17 r[i]=m; 18 } 19 20 for(int i=0;i<n;i++) 21 { 22 cin>>x[i]>>y[i]; 23 } 24 25 for(int i=0;i<k;i++) 26 { 27 int t1,t2,t3; 28 cin>>t1>>t2>>t3; 29 30 l[t1]=t2+1; 31 r[t1]=t3-1; 32 has[t1]=1; 33 } 34 35 for(int i=1;i<=n;i++) 36 { 37 has[i]+=has[i-1]; 38 } 39 40 for(int i=1;i<=n;i++) 41 { 42 for(int j=0;j<=m;j++) 43 { 44 dp[i][j]=inf; 45 } 46 } 47 48 for(int i=0;i<=n;i++) 49 { 50 for(int j=r[i]+1;j<=m;j++) 51 { 52 dp[i][j]=inf; 53 } 54 55 for(int j=l[i];j<=r[i];j++) 56 { 57 if(dp[i][j]<inf) 58 { 59 ans=i; 60 61 if(j>y[i]) 62 { 63 dp[i+1][j-y[i]]=min(dp[i+1][j-y[i]],dp[i][j]); 64 } 65 } 66 } 67 68 for(int j=l[i];j<=m;j++) 69 { 70 if(dp[i][j]<inf) 71 { 72 if(m<j+x[i]) 73 { 74 dp[i][m]=min(dp[i][m],dp[i][j]+1); 75 dp[i+1][m]=min(dp[i+1][m],dp[i][j]+1); 76 } 77 else 78 { 79 dp[i][j+x[i]]=min(dp[i][j+x[i]],dp[i][j]+1); 80 dp[i+1][j+x[i]]=min(dp[i+1][j+x[i]],dp[i][j]+1); 81 } 82 } 83 } 84 } 85 86 if(ans==n) 87 { 88 ans=inf; 89 90 for(int i=l[n];i<=r[n];i++) 91 { 92 ans=min(ans,dp[n][i]); 93 } 94 95 cout<<1<<endl<<ans<<endl; 96 } 97 else 98 { 99 cout<<0<<endl<<has[ans]<<endl; 100 } 101 102 return 0; 103 }
先写day1 以后有时间再写day 2.........
标签:
原文地址:http://www.cnblogs.com/nflslzt/p/5737875.html