hdu5765 고차원 접두사 및
2837 단어 몇 가지 상용 기교
지금 바로 고차원 접두어와:
우선 간단한 두 개의 접두사와 문자열hash종에서 흔히 볼 수 있는
예를 들어(0,0)~(1,1)
되다
(0,0) (1,0)
(0,1) (1,1)
그래서 dp[1][1]=value[0]+value[1][0]+value[0]][1]+value[1];
dp[1][0]=value[0][0]+value[1][0];dp[0][1]=value[0][0]+value[0][1];
dp[0][0]=value[0][0];
우리가 어떻게 사용해서 추가했는지 기억해 보자. 우선 우리는 먼저 dp열이다.
dp[0][0]=value[0][0],dp[1][0]=value[1][0],
dp[0][1]=value[0][0]+value[0][1],
dp[1][1]=value[1][0]+value[1][1];
이어서 dp행
dp[1][1]+=dp[0][1];
dp[1][0]+=dp[0][0];
마찬가지로 우리는 이 방법을 넓힐 수 있다
두 자리에 있을 때 먼저 x축, 그리고 y축
그러면 3차원은 x축, y축, 그리고 z축이 될 수 있다.
이렇게 계속하면 고차원 접두사와
접두사
dp[1][1][x][1][1][1]
이 dp[1][1][x][1][1] 값은 dp[][][][]의 모든 dp값의 합을 포함한다
#include
#include
#include
using namespace std;
int t, n, m;
bool isconnected[2000200];
struct edgee
{
int from, to;
};
edgee rem[500];
int edge[500];
int dp[2000200],value[1000];
int main()
{
scanf("%d", &t);
int k = 1;
while (t--)
{
scanf("%d%d", &n, &m);
for (int i = 0; i <400; i++)
value[i] = 0;
for (int i = 0; i < n; i++)
edge[i] = 0;
for (int i = 0; i < m; i++)
{
int a, b;
scanf("%d%d", &a, &b);
edge[a] |= (1 << b);
edge[b] |= (1 << a);
rem[i].from = a; rem[i].to = b;
}
int sum = 1 << n;
for (int i = 1; i < sum; i++)
isconnected[i] = 0,
dp[i]=0;
for (int i = 0; i < n; i++)
{
int ss = 1 << i;
isconnected[ss] = 1;
}
for (int i = 1; i < sum; i++)
{
for (int j = 0; j < n; j++)
{
if (isconnected[i] == 1)
break;
int kk = 1 << j;
if ((i&kk) == 0)
continue;
int tempp = kk^i;
if (isconnected[tempp] == 0)
continue;
if (edge[j] & tempp)
isconnected[i] = 1;
}
}
for (int i = 1; i < sum; i++)
{
int another = (sum-1) - i;
if (isconnected[i] && isconnected[another])
dp[i] = 1;
}
for (int i = 0; i < n; i++)
{
for (int j = 1; j < sum; j++)
{
int kk = 1 << i;
if (kk&j)
continue;
int tempp = j | kk;
dp[tempp] += dp[j];
}
}
for (int i = 0; i < m; i++)
{
int a = rem[i].from; int b = rem[i].to;
int temp1 = 1 << a; int temp2 = 1 << b;
int temp3 = 0;
for (int j = 0; j < n; j++)
{
if (j == a || j == b)
continue;
temp1 |= (1 << j); temp2 |= (1 << j);
temp3 |= (1 << j);
}
value[i] = dp[temp1] + dp[temp2] - 2 * dp[temp3];
}
printf("Case #%d: ", k++);
for (int i = 0; i