상압DP상해(1)-상압에서 상압DP+간단예제 옥수수밭 Corn Fields-POJ3254
바로 한 문제만 얘기해 봅시다. 포건 3254 옥수수밭, 여기는 바로 출제면입니다.
Corn Fields
Time Limit: 2000MS Memory Limit: 65536K
Description
Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and can’t be planted. Canny FJ knows that the cows dislike eating close to each other, so when choosing which squares to plant, he avoids choosing squares that are adjacent; no two chosen squares share an edge. He has not yet made the final choice as to which squares to plant.
Being a very open-minded man, Farmer John wants to consider all possible options for how to choose the squares for planting. He is so open-minded that he considers choosing no squares as a valid option! Please help Farmer John determine the number of ways he can choose the squares to plant.
Input
Line 1: Two space-separated integers: M and N Lines 2…M+1: Line i+1 describes row i of the pasture with N space-separated integers indicating whether a square is fertile (1 for fertile, 0 for infertile)
Output
Line 1: One integer: the number of ways that FJ can choose the squares modulo 100,000,000. Sample Input
2 3 1 1 1 0 1 0 Sample Output
9
Hint
Number the squares as follows: 1 2 3 4
There are four ways to plant only on one squares (1, 2, 3, or 4), three ways to plant on two squares (13, 14, or 34), 1 way to plant on three squares (134), and one way to plant on no squares. 4+3+1+1=9.
제목 대의: 밭 한 뙈기를 주고 1곳에서만 옥수수를 얻을 수 있다. 그리고 옥수수의 앞뒤 좌우에 옥수수가 있을 수 없다. 몇 가지 방법이 있느냐고 묻는다.
우리가 방금 말한 방법에 따르면 먼저 폭력적으로 매거해야 한다. 단지 이 문제는 짝수 행렬과 약간 다르다. 이 문제는 우리가 각 층의 상태를 매거해야 그의 방안수(각 줄의 실행 가능한 상태는 하나의 방안이라고 할 수 있다)를 계산할 수 있다. 그래서 우리는 폭력(0부터 비교적 편리하다):
for (int i=0; i<n; i++) //
for (int j=0; j<(1<<m); j++) //
상태 0000000에서 모두 심지 않은 상태에서 111111까지 모두 심는 상태입니다.
그리고 이 줄의 상태에 대해 우리는 그가 입력한 텍스트에 부합되는지, 그리고 이 줄이 하나를 사이에 두고 다시 놓는 제약 조건을 충족시키는지 판정해야 한다. 그러면 우리의 코드는 확장될 수 있다.
for (int i=0; i<n; i++) //
for (int j=0; j<(1<<m); j++) //
if (!ok(i,j)) continue;//
// ok :
int ok(int r,int s)
{
for (int i=0; i<m; i++){//
if ((s&(1<<i)) && !a[r][i]) return 0;
}
for (int i=0; i<m; i++){//
if ((s&(1<<i)) && (s&(1<<(i+1)))) return 0;
}
return 1;
}
여기서'&': 1&1=1,1&0=0을 설명하면 s의 i위가 1인지 아닌지를 직접 판단할 수 있다.첫 줄은continue 다음에 dp[i][j]=1을 넣는다.좋습니다. 물론 판단을 추가하는 것이 필요합니다. 다음은 아래 줄의 수를 처리하는 것입니다. 아래 줄의 수는 본 줄의 수가 놓인 상태수만 있는 것이 아니라 앞줄의 상태수도 넣습니다. 이렇게 해야 전체 방안수입니다.
for (int k=0; k<(1<<m); k++) { //
if ((j&k)==0) dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
}
그 중에서 j는 이 줄의 상태이다. 우리는 윗줄의 상태를 일일이 열거하여 구속 조건을 충족시킬 수 있는지 확인한다.(j&k)==0은 j와 k의 0과 1이 서로 엇갈리는 것을 가리킨다. 즉, 상태가 성립되는 것을 말한다.그러면 우리는 본 줄의 이 j상태와 모든 이전 줄의 일치하는 상태 k를 dp에 넣고 다음 줄의 준비를 합니다.
그러면 마지막 줄의 각 상태의 합은 우리의 방안 총수입니다. 다음은 AC 코드입니다. (POJ는 만능 헤더 파일을 지원하지 않습니다. (* ^; ^ *)
//#include
#include
using namespace std;
typedef long long ll;
const ll mod=1e8;
int a[15][15],b[15][15];
ll ans=0,dp[15][1<<15],m;
int ok(int r,int s);
int main()
{
int n;
scanf ("%d%d",&n,&m);
for (int i=0; i<n; i++){
for (int j=0; j<m; j++){
scanf ("%d",&a[i][j]);
}
}
for (int i=0; i<n; i++){//
for (int j=0; j<(1<<m); j++){//
if (!ok(i,j)) continue;
if (i==0) {
dp[i][j]=1;
continue;
}
for (int k=0; k<(1<<m); k++){//
if ((j&k)==0) dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
}
}
}
for (int i=0; i<(1<<m); i++){
ans=(ans+dp[n-1][i])%mod;
}
printf ("%lld
",ans);
return 0;
}
int ok(int r,int s)
{
for (int i=0; i<m; i++){
if ((s&(1<<i)) && !a[r][i]) return 0;
}
for (int i=0; i<m; i++){
if ((s&(1<<i)) && (s&(1<<(i+1)))) return 0;
}
return 1;
}
물론 더 빠른 방법은 제약조건에 부합되는 모든 수를 저장한 다음에 매거하는 것이다. 그 다음에 우리는 그의 줄마다 제약조건에 부합되는지 판단할 필요가 없다. 단지 이것은 직관적이지 않고 이해하기 어려워서 초보자에게 이렇게 쓰는 것을 권장하지 않는다...나의 블로그 상압 DP 상해(2)에 구체적으로 소개되어 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Rails Turbolinks를 페이지 단위로 비활성화하는 방법원래 Turobolinks란? Turbolinks는 링크를 생성하는 요소인 a 요소의 클릭을 후크로 하고, 이동한 페이지를 Ajax에서 가져옵니다. 그 후, 취득 페이지의 데이터가 천이 전의 페이지와 동일한 것이 있...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.