AGC 017

A
dp

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 110;

int n,p;
int a[maxn];
ll f[maxn][2];

int main()
{
    scanf("%d%d",&n,&p);
    f[0][0]=1ll;
    for(int i=1;i<=n;i++)
    {
        int x; scanf("%d",&x); x&=1;
        f[i][0]=f[i-1][0],f[i][1]=f[i-1][1];
        if(x) f[i][1]+=f[i-1][0],f[i][0]+=f[i-1][1];
        else f[i][1]+=f[i-1][1],f[i][0]+=f[i-1][0];
    }
    printf("%lld\n",f[n][p]);

    return 0;
}

B
转化模型,n-1个数,每个数绝对值在C~D之间,问存不存在一种方案使他们的和为A-B
考虑去掉绝对值,枚举负数个数i,那么i个负数的和的范围,n-1-i个正数和的范围就都知道了,两个不等式相加,看A-B在不在范围内

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 1100;

ll n,a,b,c,d,u;

int main()
{
    scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&c,&d);
    u=b-a; n--;
    ll l=0,r=0,L=c*n,R=d*n;
    for(int i=n;i>=0;i--)
    {
        if(L+l<=u&&u<=R+r) { puts("YES");return 0; }
        L-=c,R-=d;
        l-=d,r-=c;
    }
    puts("NO");

    return 0;
}

C
转化为线段覆盖的模型就很妙了
若权为x的球有k个,它能覆盖x-k~x之间的线段,易证0~n全部被覆盖时不需要修改,若没有全部覆盖,易证未被覆盖的线段数就是至少要修改的次数

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 210000;

int n,m;
int v[maxn];
int p[maxn],a[maxn];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&p[i]),a[p[i]]++;
    for(int i=1;i<=n;i++) 
        for(int j=max(i-a[i],0);j<i;j++) v[j]++;

    int ans=0;
    for(int i=0;i<n;i++) if(!v[i]) ans++;

    while(m--)
    {
        int x,y; scanf("%d%d",&x,&y);
        int c=p[x];
        if(c-a[c]>=0&&v[c-a[c]]==1) ans++;
        if(c-a[c]>=0) v[c-a[c]]--; a[c]--;
        c=y; p[x]=c;
        if(c-a[c]-1>=0&&!v[c-a[c]-1]) ans--;
        a[c]++; if(c-a[c]>=0) v[c-a[c]]++;
        printf("%d\n",ans);
    }

    return 0;
}

D
经典博弈,将一条长度为x的链视为一堆石子数为x的一堆石子,每个点的所有孩子分别各自合并到一条链,这个点相当于在这些堆石子中决策,将sg异或起来,合并成一条链

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 110000;

int n,m;
struct edge{int y,nex;}a[maxn<<1]; int len,fir[maxn];
inline void ins(const int x,const int y){a[++len]=(edge){y,fir[x]};fir[x]=len;}

int sg[maxn];

void dp(const int x,const int fa)
{
    sg[x]=0;
    for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(y!=fa)
    {
        dp(y,x); sg[x]^=(sg[y]+1);
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int x,y; scanf("%d%d",&x,&y);
        ins(x,y); ins(y,x);
    }

    dp(1,0);
    if(sg[1]) puts("Alice");
    else puts("Bob");

    return 0;
}

E
尝试去构造一个积木间的匹配关系
我们用二元组 (l,r) 代表每个积木,
若一个积木 C=0,l=+A,C0,l=A,D=0,r=B,D0,r=+D
如果在 (l,r) 后面能拼上 (l,r) ,需要满足r=l’,否则就是不拼的情况,要求r<0,l’>0。
建一个图,点标号-H~+H,对每个二元组 (l,r) ,l向r连一条有向边
题目可以转化成判断是否可以将图中的边分成若干条链要求每条链从正权点出发,负权点结束。
对于正权点,要求outdegree>=indegree,
负权点要求indegree>=outdegree,
且对于同种每个弱联通的联通块,其中必定要有出入度不等的点
满足这些条件后,对于每个弱联通块,如果它没有环,易知一定存在解;若有环,环一定和链相接,可以通过构造,把环拼在链上。

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 410000;

int n,m=800;

int fa[maxn];
int findfa(const int x){return fa[x]==x?x:fa[x]=findfa(fa[x]);}

int d[maxn],v[maxn],ok[maxn];

int main()
{
    scanf("%d%*d",&n);
    for(int i=1;i<m;i++) fa[i]=i;
    for(int i=1;i<=n;i++)
    {
        int a,b,c,D,l,r; scanf("%d%d%d%d",&a,&b,&c,&D);
        l=!c?a:-c;
        r=!D?-b:D;
        l+=400,r+=400;
        d[l]++,d[r]--; v[l]=v[r]=1;
        fa[findfa(l)]=findfa(r);
    }
    for(int i=1;i<=400;i++) if(d[i]>0) return puts("NO"),0;
    for(int i=400;i<m;i++)  if(d[i]<0) return puts("NO"),0;

    for(int i=1;i<m;i++) if(d[i]) ok[findfa(i)]=1;
    for(int i=1;i<m;i++) v[findfa(i)]|=v[i];

    for(int i=1;i<m;i++) if(i==findfa(i)&&v[i]&&!ok[i]) 
        return puts("NO"),0;
    puts("YES");

    return 0;
}

F
考虑一种朴素的dp,f[i][k]表示处理到第i条链,第i条链在1~n-1层走的方向为k
直接枚举下一条链的状态l转移dp,是 O(m4n) 的,考虑合并类似的合法状态
令s[i]表示一个状态前i位1的数量,下一条链的状态l如果是合法的,当且仅当对于任意的u,有sk[u]<=sl[u]
所以我们可以利用这个合并一些s[u]相同的状态
(应该有很多种状态定义都行)以下是题解的状态定义:
令f[i][j][k]表示处理到第i条链的第j次操作且前j次操作与k相同,转移的时候枚举第j+1次操作,
如果往左走:要求k的第j+1位为0且这一位没有往右的限制
如果往右:要求没有往左的限制,如果k的j+1位为1就可以直接转移至f[i][j+1][k],否则把k往后第一个1移到j+1位,转移至f[i][j+1][newk]

注意空间,把i和j都滚动

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define lowbit(x) x&(-x)
#define _ %Mod
#define __ %=Mod
using namespace std;

const int maxn = 22;
const int maxm = 22;
const int maxk = 1100000;
const ll Mod = 1e9+7;

int n,m,K;
int ci[maxm][maxn];
ll f[2][maxk];

int main()
{
    scanf("%d%d%d",&n,&m,&K); n--;
    memset(ci,-1,sizeof ci);
    for(int i=1;i<=K;i++)
    {
        int x,y,z; scanf("%d%d%d",&x,&y,&z);
        ci[x][y-1]=z;
    }

    int al=1<<n;
    int now=0; f[0][0]=1ll;
    for(int i=1;i<=m;i++) for(int j=0;j<n;j++) 
    {
        for(int k=0;k<al;k++) if(f[now][k])
        {
            ll tmp=f[now][k];

            if(!(k>>j&1)&&ci[i][j]!=1) (f[!now][k]+=tmp)__;
            if(ci[i][j]==0) continue;
            if(k>>j&1) (f[!now][k]+=tmp)__;
            else
            {
                int lk=k&(1<<j+1)-1,nk=k^lk;
                nk=nk^lowbit(nk)^lk^1<<j;
                (f[!now][nk]+=tmp)__;
            }
        }
        memset(f[now],0,sizeof f[now]); now=!now;
    }
    ll ans=0;
    for(int k=0;k<al;k++) (ans+=f[now][k])__;
    printf("%lld\n",ans);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Matlab中,AGC(Automatic Gain Control)是一种用于自动调节信号增益的技术AGC系统的作用是保持信号在一个适当的功率范围内,以便有效地处理和分析信号。使用Matlab可以实现数字AGC系统的建模与仿真。 在Matlab中使用Simulink环境进行数字AGC的建模与仿真可以通过以下步骤实现: 1. 使用Simulink库中的信号源模块生成输入信号。可以使用随机信号或特定模式的信号作为输入。 2. 将信号传递到AGC模块,该模块可以从Simulink库中选择或自定义。 3. 配置AGC模块的参数,例如增益平均系数、增加步进、减小步进、参考级别、上限和下限等。 4. 将AGC模块的输出与其他模块连接,例如显示模块或数据处理模块。 5. 运行模型并观察AGC系统的输出结果。 通过以上步骤,您可以使用Matlab中的Simulink环境建立数字AGC模型,并使用Matlab实现数字AGC系统。需要注意的是,在实际应用中,数字AGC系统的复杂程度可能会更高,需要根据具体情况进行调整和优化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [基于Simulink的数字AGC建模与仿真](https://blog.csdn.net/CodeWG/article/details/130591628)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值