程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU--4901--The Romantic Hero

HDU--4901--The Romantic Hero

編輯:C++入門知識

HDU--4901--The Romantic Hero


The Romantic Hero

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1112 Accepted Submission(s): 459

Problem Description There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

You may wonder why this country has such an interesting tradition? It has a very long story, but I won't tell you :).

Let us continue, the party princess's knight win the algorithm contest. When the devil hears about that, she decided to take some action.

But before that, there is another party arose recently, the 'MengMengDa' party, everyone in this party feel everything is 'MengMengDa' and acts like a 'MengMengDa' guy.

While they are very pleased about that, it brings many people in this kingdom troubles. So they decided to stop them.

Our hero z*p come again, actually he is very good at Algorithm contest, so he invites the leader of the 'MengMengda' party xiaod*o to compete in an algorithm contest.

As z*p is both handsome and talkative, he has many girl friends to deal with, on the contest day, he find he has 3 dating to complete and have no time to compete, so he let you to solve the problems for him.

And the easiest problem in this contest is like that:

There is n number a_1,a_2,...,a_n on the line. You can choose two set S(a_s1,a_s2,..,a_sk) and T(a_t1,a_t2,...,a_tm). Each element in S should be at the left of every element in T.(si < tj for all i,j). S and T shouldn't be empty.

And what we want is the bitwise XOR of each element in S is equal to the bitwise AND of each element in T.

How many ways are there to choose such two sets? You should output the result modulo 10^9+7.

Input The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains a integers n.
The next line contains n integers a_1,a_2,...,a_n which are separated by a single space.

n<=10^3, 0 <= a_i <1024, T<=20.
Output For each test case, output the result in one line.
Sample Input
2
3
1 2 3
4
1 2 3 3

Sample Output
1 
4

題意:把這個數列取一些數分成兩部分,要求x中所有數字都小於b中數字,求這些分配方案中,x裡面的數全部“異或”起來的值等於y裡面的數全部“與”起來的值相同的方案數,x和y中不能為空


做法,DP,用分割線的方法把數列分成兩段,然後用x[i][j]來代表從開頭知道第i個數字這些數字能組成的集合的總方案數,y[i][j]和x[i][j]差不多,但是有一點不同,就是當下標大於j的時候,x[j]中所有的方案x[i]中都存在,而在y[i]中,只記錄和第i和數字進行了“與”運算的方案數,這樣就不會重復了,因為我在y[i][j]的時候是和x[i-1][j]匹配,x[i-1][j]然後分割線左移的任何的x[i1][j1]的方案在x[i][j]中都有,所以我只在這個時候匹配一次

例如:

4

1 2 3 3

x[1]={1}

x[2]={1,2,1^2}

x[3]={1,2,3,1^2,1^3,2^3,1^2^3}

x[4]就不用計算了,因為去了第四個數字那麼y裡面就為空,違反條件了


y[4]={3}

y[3]={3,3&3} //這裡的3是第三個數字的3,第四個數字的三在y[4]中出現並且已經與x[3]匹配過了,y[3]裡面是從最後一個數字到第三個數字中和第三個數字3與運算得到的方案

y[2]={2,2&3,2&3&3}


在y[4]和x[3]匹配的時候就等於把y[4]與x[2]、y[4]與x[1]都匹配完了,畢竟x[3]包含了x[2],x[1]中所有的方案嘛

然後這個y[4]的方案就不用傳遞給y[3]了,不然又要與x[2],x[1]去匹配,這樣就重復了,但是還是要保存式記錄下來,因為前面隨便一個數字都可以和它形成一個新的集合


這個題誰會相信我做了一天?當初要了解題意的時候找博客,結果只有三條,現在一下子就成幾頁了,而且我一直WA在一個代碼,卻在博客看到了一個和自己一模一樣的代碼,你應該要知道這種情況下我會懷疑他的也是WA,結果他的AC,我看了2小時都沒看出所以然,結果讓別人一看。。。我滴天那,1024我寫成了1014,我擦你妹妹蛋蛋的,天坑


#include 
#include 
#include 
#define LL __int64
#define mod 1000000007
using namespace std;
LL x[1111][2222],y[1111][2222];	//x:分割線左邊,y:分割線右邊,如x[i][j]代表分割線在第i個數字和i+1個數字中間時候的異或結果是j的方案數
int main (void)
{
    int t,n,i,j,k,l;
    int s[1010];
    scanf("%d",&t);
    while(t--&&scanf("%d",&n))
    {
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&s[i]);
            x[i][s[i]]=1;	//單個元素也算一個方案
            for(j=0;j<1024;j++)	//遍歷所有值,把前一條分割線的方案全部異或到當前分割線的方案中來
            {
                x[i][j]=(x[i][j]+x[i-1][j])%mod;	//傳遞方案數,這就是x[i]包含了所有x[i-j](j>0)中方案數的原因
                x[i][j^s[i]]=(x[i][j^s[i]]+x[i-1][j])%mod;	//把這些方案異或當前的這個值得到的新的方案存起來
            }
        }
        LL sum=0;
        for(i=n;i>1;i--)
        {
            y[i][s[i]]=1;	//單個元素也算一個方案
            for(j=0;j<1024;j++)	//遍歷所有值
            if(y[i+1][j])	//如果這個值為j的方案數存在
            y[i][j&s[i]]=(y[i][j&s[i]]+y[i+1][j])%mod;	//那麼把這個方案跟當前元素與運算之後得到新方案
            for(j=0;j<1024;j++)	//把得到的所有新方案加起來
            sum=(sum+x[i-1][j]*y[i][j])%mod;
            for(j=0;j<1024;j++)	//把先前的舊方案傳遞過來
            y[i][j]=(y[i][j]+y[i+1][j])%mod;
        }
        printf("%I64d\n",sum);
    }
    return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved