20160602常规赛总结

Task1蛮有趣
Task2暴力dp==听老师讲了什么前缀和愣是没想通暴力的dp为什么要前缀和。。如果有前缀和我的dp就是O(n)了。。
Task3有一些问题
比如为什么关于开关问题同一个区间不会反转两次,虽然理由很有道理,但是我理解不通。。智商不够。。
那么以后只好记结论了
最后一题放一下题目讲一下思路。

图染色

Description

给定一个n个点,m条边的无向图。每条边都有一种颜色,’R’或者’B’;
每次染色可以选择一个点,把与这个相连的边的颜色都翻转。
求最少选择几个点进行染色,使得所有边的颜色最后都相同!

Solution
这个标点有点鬼。。
反正大概知道是开关问题了,那就很简单了。
首先枚举每个联通块的颜色。
并查集搞一下就差不多了。
怎么都觉得自己是第一次敲影子并查集。

[源代码]:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
#define pb push_back
#define vec vector<int>
const int M=4e5+5;
struct node{int to;bool c;};
vector<node>G[M];
vec Nod;
int n,m,fa[M],cnt[M];
bool mark[M];
inline void rd(int &a){
    a=0;char c;
    while(c=getchar(),!isdigit(c));
    do a=a*10+(c^48);
        while(c=getchar(),isdigit(c));
}
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void Min(int &a,int b){if(a==-1||a>b)a=b;}
void dfs(int v,const bool clr){
    mark[v]=1;
    Nod.pb(v);
    for(int i=0;i<G[v].size();++i){
        node u=G[v][i];
        if(u.c==clr){
            int f1=find(v),f2=find(u.to);
            if(f1!=f2){
                fa[f2]=f1;
                cnt[f1]+=cnt[f2];
            }
            f1=find(v+n),f2=find(u.to+n);
            if(f1^f2){
                fa[f2]=f1;
                cnt[f1]+=cnt[f2];
            }
        }
        else{
            int f1=find(v),f2=find(u.to+n);
            if(f1!=f2){
                fa[f2]=f1;
                cnt[f1]+=cnt[f2];
            }
            f1=find(v+n),f2=find(u.to);
            if(f1!=f2){
                fa[f2]=f1;
                cnt[f1]+=cnt[f2];
            }
        }
        if(!mark[u.to])dfs(u.to,clr);
    }
}
int main(){
    int size = 256 << 20; // 256MB
    char *p = (char*)malloc(size) + size;
    __asm__("movl %0, %%esp\n" :: "r"(p));
    cin>>n>>m;
    char s[2];
    for(int i=1,a,b,c;i<=m;++i){
        rd(a),rd(b);scanf("%s",s);c=s[0]=='B';
        G[a].pb((node){b,(bool)c}),G[b].pb((node){a,(bool)c});
    }
    int ans1=0,ans2=0;
    for(int i=1;i<=n;++i)fa[i]=i,fa[i+n]=n+i,cnt[i]=1;
    for(int i=1;i<=n;++i)
        if(!mark[i]){
            Nod.clear();
            int res1=-1;
            dfs(i,0);
            int ct=0;
            for(int j=0;j<Nod.size();++j){
                if(Nod[j]==fa[Nod[j]])++ct;
                if(Nod[j]+n==fa[Nod[j]]+n)++ct;
            }
            if(ct==1)res1=M;
            else{
                for(int j=0;j<Nod.size();++j){
                    int v=Nod[j];
                    if(fa[v]==v)Min(res1,cnt[v]);
                    if(fa[v+n]==v+n)Min(res1,cnt[v+n]);
                    fa[v]=v,fa[v+n]=v+n;
                    cnt[v]=1,cnt[v+n]=0;
                    mark[v]=0;
                }
            }
            Nod.clear();
            dfs(i,1);
            int res2=-1;
            ct=0;
            for(int j=0;j<Nod.size();++j){
                if(Nod[j]==fa[Nod[j]])++ct;
                if(Nod[j]+n==fa[Nod[j]]+n)++ct;
            }
            if(ct==1)res2=M;
            else{
                for(int j=0;j<Nod.size();++j){
                    int v=Nod[j];
                    if(fa[v]==v)Min(res2,cnt[v]);
                    if(fa[v+n]==n+v)Min(res2,cnt[v+n]);
                }
            }
            ans1+=res1;
            ans2+=res2;
        }
    cout<<min(ans1,ans2)<<endl;
    return 0;
}


代码略长,略丑。。但是思路很简单咯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NBA常规赛结果的预测可以使用Matlab中的机器学习方法来完成。机器学习是一种使用统计学习算法来训练模型并进行预测的方法,对于NBA常规赛结果的预测也可以采用类似的思路。 首先,我们需要准备训练数据。训练数据可以包括以往的NBA常规赛数据,包含双方球队的比赛记录、球队成员的数据以及比赛的具体参数等等。这些数据可以从公开的数据源中获取,比如NBA官方网站。 接下来,我们需要选取合适的机器学习算法来训练模型。在预测NBA常规赛结果的任务中,可以选择一些常用的分类算法,如逻辑回归、支持向量机、决策树等。这些算法在Matlab中都可以找到相应的工具包和函数进行使用。 然后,我们把已有的训练数据输入到机器学习模型中进行训练。训练过程会根据具体的算法和训练数据,自动寻找最优的模型参数,以便能够准确地预测NBA常规赛结果。 最后,我们可以使用训练好的模型对新的比赛数据进行预测。根据比赛双方的数据输入到模型中,模型会根据之前的训练经验给出对比赛结果的预测。 需要注意的是,由于NBA常规赛中存在许多因素影响比赛结果,如球队的实力、球员伤病、比赛场地等等,完全准确地预测比赛结果是非常困难的。因此,机器学习只是一种预测方法,其结果可能存在一定的误差。在使用机器学习预测NBA常规赛结果时,我们要对结果保持一定的客观和理性,不能过分依赖模型的预测。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值