zoukankan      html  css  js  c++  java
  • 牛客练习赛41 B. 666RPG

      题目大意就是给n个数,然后有n个回合,在第i个回合操作有2种,一种是对当前数*-1,第二种是对当前数+ai,问你n回合后数变成-666的操作方案数是多少?另外数的初始值是0,还有在一个合法的方案里,不能有某个回合结束后数变成了666

      这题用的是计数dp,定义dp[i][j]表示第i个回合结束之后,数变成j的方案个数。初始化是dp[0][0]=1,其余为0。状态转移的话是dp[i][-j]+=dp[i-1][j],dp[i][j+a[i]]+=dp[i-1][j],然后跳过666的转移。然后因为数的变化范围是-666*300到666*300当时数组的下标是不能为负数的,所以在这里做了个映射,把-666*300到666*300这个区间映射到-666*300+700*300到666*300+700*300这个区间了,相当于第i个回合结束后数为j的方案数为dp[i][j+700*300],开二维爆内存了,然后就滚掉一维。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define tmp 210000
    const ll mod=1e8+7;
    ll dp[2][420000];
    int a[305];
    int main()
    {
        int n,pos=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&(a[i]));
        dp[0][0+tmp]=1LL;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=(420000-1);j++) dp[(pos+1)%2][j]=0LL;
            for(int j=-199800;j<=199800;j++)
                if(dp[pos][j+tmp])
                {
                    if(j+a[i]!=666)
                        dp[(pos+1)%2][j+a[i]+tmp]=(dp[(pos+1)%2][j+a[i]+tmp]+dp[pos][j+tmp])%mod;
                    if((-1*j)!=666)
                        dp[(pos+1)%2][-1*j+tmp]=(dp[(pos+1)%2][-1*j+tmp]+dp[pos][j+tmp])%mod;
                }
            pos=(pos+1)%2;
            if(i==n)
            {
                cout<<dp[pos][-666+tmp]<<endl;
                return 0;
            }
        }
    }
    
  • 相关阅读:
    JavaWeb--HttpSession案例
    codeforces B. Balls Game 解题报告
    hdu 1711 Number Sequence 解题报告
    codeforces B. Online Meeting 解题报告
    ZOJ 3706 Break Standard Weight 解题报告
    codeforces C. Magic Formulas 解题报告
    codeforces B. Sereja and Mirroring 解题报告
    zoj 1109 Language of FatMouse 解题报告
    hdu 1361.Parencodings 解题报告
    hdu 1004 Let the Balloon Rise 解题报告
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754806.html
Copyright © 2011-2022 走看看