zoukankan      html  css  js  c++  java
  • 2020-10-13 联赛模拟测试15

    T1游戏

    把每个武器的两个属性连上边,即将武器看作边,将属性看做点。
    对于树联通块,显然不选最大的节点(属性)。
    对于非树联通块,因为每个武器可以选两个相邻节点之一,显然每个节点(属性)都可以被选。

    T2嘟嘟噜

    n个人,每次报到m的死
    初始ans = 0, 枚举 2 <= i <= n, 每次 (ans+=m)%=i;
    最后 ans + 1 即答案
    本题n达到了1e9显然O(n)不可过,于是考虑优化
    n 很大, m 相对较小
    对于每次取模,发现,当i很大时,取模很可能没用上,所以可以将加法转化为乘法

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    int n,m,ans,siz;
    int main(){
    	freopen("mayuri.in","r",stdin);
    	freopen("mayuri.out","w",stdout);
    	int t;scanf("%d",&t);
    	while(t--){
    		scanf("%d%d",&n,&m);
    		ans=0;
    		for(int i=2;i<=n;i+=siz){
    			siz=max(1,min(n-i+1,(i-ans)/m));
    			(ans+=m*siz)%=(i+siz-1);
    		}
    		printf("%d
    ",ans+1);
    	}
    	return 0;
    }
    

    T3 天才绅士少女助手克里斯蒂娜

    开方得:(sumlimits_{i=l}^{r-1} sumlimits_{j=i+1}^r x_i^2 y_j^2 x_j^2 y_i^2 -2*x_i y_i x_j y_j)
    发现如果 将(i,j)都在([l,r])内枚举,即(sumlimits_{i=l}^r sumlimits_{j=l}^r x_i^2 y_j^2 + x_j^2 y_i^2 - 2 x_i y_i x_j y_j)
    恰好为原式2倍
    (sumlimits_{i=l}^r sumlimits_{j=l}^r 2 x_i^2 y_j^2 - sumlimits_{i=l}^r sumlimits_{j=l}^r 2 x_i y_i x_j y_j)
    原式就是:
    (sumlimits_{i=l}^r sumlimits_{j=l}^r x_i^2 y_j^2 - sumlimits_{i=l}^r sumlimits_{j=l}^r x_i y_i x_j y_j)
    ((sumlimits_{i=l}^{r}x_i^2) imes(sumlimits_{i=l}^{r}y_i^2) - (sumlimits_{i=l}^{r}x_iy_i)^2)
    用树状数组维护
    (sumlimits_{i=l}^{r}x_i^2 和 sumlimits_{i=l}^{r}y_i^2 和 sumlimits_{i=l}^{r} x_i*y_i) 即可
    每次单点修改,区间查询

    T4凤凰院凶真((LCIS)

    最长公共上升子序列 , (f[i][j])表示对于(a[])的前(i)个,(b[])的前(j)个,且以(b[j])结尾的最大长度
    (a[i]!=b[j] : f[i][j]=f[i-1][j];)
    (a[i]==b[j] : f[i][j]=f[i-1][k]+1 (0<=k<j))
    (O(n^3))
    考虑优化:
    可以发现枚举(k)(a[i])是不变的,只要(b[j]==a[i]),(f[i][j])就会被前面的最优决策点+1更新
    那么我们只需要在枚举j的时候顺便更新一个最优决策点即可避免枚举k
    复杂度 (O(n^2))
    注意记录来源回溯的时候,不能用一维数组,要用二维数组记录上一个选什么,否则你会看到十分神奇的结果

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=5e3+5;
    int n,a[maxn];
    int m,b[maxn];
    int f[maxn][maxn];
    int fr[maxn][maxn];
    int sta[maxn],top;
    int ans;
    void back(int i,int j){
    	if(!i||!j) return;
    	if(fr[i][j]!=j) sta[++top]=b[j];
    	back(i-1,fr[i][j]);
    }
    int main(){
    	freopen("phoenix.in","r",stdin);
    	freopen("phoenix.out","w",stdout);
    	scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    	scanf("%d",&m); for(int i=1;i<=m;++i) scanf("%d",&b[i]);
    	for(int i=1;i<=n;++i){
    		int val=f[i-1][0],pos=0;
    		for(int j=1;j<=m;++j){
    			if(a[i]!=b[j]){
    				f[i][j]=f[i-1][j];
    				fr[i][j]=j;
    			}
    			else{
    				f[i][j]=val+1;
    				fr[i][j]=pos;
    			}
    			if(b[j]<a[i]&&f[i-1][j]>val){
    				val=f[i-1][j];
    				pos=j;
    			}
    		}
    	}
    	int ans=0;
    	for(int i=1;i<=m;++i) if(f[n][i]>f[n][ans]) ans=i;
    	printf("%d
    ",f[n][ans]);
    	back(n,ans);
    	for(int i=top;i>=1;--i) printf("%d ",sta[i]);
    	return 0;
    }
    
  • 相关阅读:
    暴力,DFS,比较字符串
    暴力求解最大乘积
    油田!
    八皇后的问题
    巡逻的机器人
    骑士的移动
    二叉树遍历
    新兵训练(=@__@=)
    打牌~~~
    八皇后
  • 原文地址:https://www.cnblogs.com/Lour688/p/13809399.html
Copyright © 2011-2022 走看看