hdu4346 枚举思维

本文提供了一道来自HDU OJ的题目4346的解答思路及代码实现,该题涉及组合数学与动态规划,旨在求解在已知部分旗子颜色的情况下,如何插入剩余旗子使道路美观的不同方式的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

Problem Description
There is a road from city A to city B.On the road,there are N positions(indexed from 0 to N-1).In order to celebrate the Multi-University training,the mayor of city A commands a worker to insert N flags on the N positions.The color of a flag is either red or green.We call the road is beautiful if and only if there exists at least one pair of non-negative integers (a,b) (0<=a<b<N and (a+b) is an even number) such that both a-th flag and b-th flag are red and (a+b)/2-th flag is green.Otherwise we call the road is ugly.Now,some positions have already been inserted flags.In order to make the road beautiful,the worker must carefully insert the flags on the positions which haven't been inserted.He wants to know how many different types of beautiful road he can make.The type of the road only depends on the flags' color.
 

Input
The first line of the input is the number of cases. On each case there is a line consists of a string.The length of the string is N.(0<=N<=800).The i-th character of the string is 'R' or 'G' or '?'.'R' means the flag on the i-th position which has been inserted is red.'G' means the flag on the i-th position which has been inserted is green.'?' means the i-th position hasn't been inserted a flag.
 

Output
A single line with the number of different types of road the worker can make, modulo 1,000,000,007.
 

Sample Input
  
4 ?G RG? ??? ????
 

Sample Output
  
0 1 1 4
/**
http://blog.youkuaiyun.com/julyana_lin/article/details/7849006
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
const int mod=1000000007;

LL mod_pow(int a,int n,int p)
{
    LL ret=1;
    LL A=a;
    while(n)
    {
        if(n&1)
        {
            ret=(ret*A)%p;
        }
        A=(A*A)%p;
        n>>=1;
    }
    return ret;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        char a[1005];
        scanf("%s",a);
        int n=strlen(a);
        int unknown=0,r_num=0;
        for(int i=0;i<n;i++)
        {
            if(a[i]=='?')
                unknown++;
            else if(a[i]=='R')
                r_num++;
        }
        LL unbea=(r_num==0);
        for(int i=0;i<n;i++)
        {
            if(a[i]=='R'||a[i]=='?')
            {
                int x=(a[i]=='R');
                unbea=(unbea+(x==r_num))%mod;
                for(int len=1;len+i<n;len+=2)
                {
                    int y=x;
                    for(int j=i+len;j<n;j+=len)
                    {
                        y+=(a[j]=='R');
                        if(a[j]=='G')break;
                        unbea=(unbea+(y==r_num))%mod;
                    }
                }
            }
        }
        printf("%I64d\n",mod_pow(2,unknown,mod)-unbea);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值