2020百度之星

(三)

Chess(经典DP)

http://acm.hdu.edu.cn/showproblem.php?pid=6787

思路:

考虑如果棋盘上连续放置了 11 个传送器,那么这个区域就是无法通过骰子跨过的。而对于一个区域而言,只要上面没有连续 11 个传送器,我们就可以通过控制骰子而成功达到每个可达到的点。由此可以得到一个 dp 方程:设 f[i][j][k] 表示当前考虑到第i个格子,已经用了j个传送器,包括i号位置有连续k个传送器。那么我们的决策就是第i号位置是否放传送器。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod= 1e9+7;
inline int read(){
    int k=0,j=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') j=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){k*=10;k+=ch-'0';ch=getchar();}
    return j*k;
}
int dp[1005][1005][11];
int main()
{
    int t;scanf("%d",&t);
    while(t--){
        int n=read(),m=read();
        memset(dp,0,sizeof(dp));
        dp[1][0][0] = 1;
        for(int i=2;i<=n;i++){
            for(int j=0;j<=m;j++){
                for(int k=0;k<=10;k++) dp[i][j][0]=(dp[i-1][j][k]+dp[i][j][0])%mod;
                if(i!=n&&j) for(int k=1;k<=10;k++)
                    dp[i][j][k]=(dp[i][j][k]+1ll*dp[i-1][j-1][k-1]*(i-1)%mod)%mod;
            }
        }
        printf("%d\n",dp[n][m][0]?dp[n][m][0]:-1);
    }
    return 0;
}

 复赛

1001 Battle for Wosneth

用gcd化为最简分数会wa,我也不造为啥。

直接来就可以过了,化简公式,分母幂mod-2,注意mod处理。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll quickp(ll a,ll n){
    ll ans=1;
    a%=mod;
    while(n){
        if(n&1) ans=ans*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return ans;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        ll m,p,q;
        scanf("%lld%lld%lld",&m,&p,&q);
        printf("%lld\n",((100*(m*(p-q))%mod+p*q)%mod*quickp(100*p,mod-2)%mod+mod)%mod);
    }
}

1002 Binary Addition

最优操作方法一定是把某个前缀改成全部为1,然后加1,然后直接改不同的位置。

枚举操作的是哪一个前缀。

当前如果是1,则利用一次改变次数,使他成为0。

#include<bits/stdc++.h>
using namespace std;
#define re register
int a[100004],b[100004],dif[100004];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(dif,0,sizeof(dif));
        int n;
        scanf("%d",&n);
        getchar();
        for(re int i=1;i<=n;++i){
            re char ch=getchar();
            a[i]=ch^48;
        }
        getchar();
        for(re int i=1;i<=n;++i){
            re char ch=getchar();
            b[i]=ch^48;
            dif[i]=dif[i-1];
            if(a[i]!=b[i]) dif[i]++;
        }
        dif[n+1]=dif[n];
        a[n+1]=b[n+1]=0;
        int ans=dif[n],tmp;
        int num0=0,num1=0;
        for(int i=1;i<=n+1;++i){
            tmp=0;
            if(a[i]) tmp++;
            tmp+=num0;
            tmp++;
            tmp+=num1;
            tmp+=dif[n]-dif[i];
            if(!b[i]) tmp++;
            ans=min(tmp,ans);
            if(!a[i]) num0++;
            if(b[i]) num1++;
        }
        printf("%d\n",ans);
    }
}

 

posted @ 2020-07-26 22:05  IcecreamArtist  阅读(201)  评论(0编辑  收藏  举报