codeforces 401D
먼저 dp[1<<18][100]의 수조를 구축하는데 이 수조는 의미가 있다.다음과 같이 설명합니다.
1차원: 하나의 숫자, 예를 들어 123123453에 대해 각각 0과 1로 사용했는지 여부를 표시할 수 있다. 그러면 2진법으로 표현할 수 있고 제목의 18자리 길이에 해당하는 크기의 수조를 구축할 수 있다.
2차원: 이 상태의 나머지를 나타낸다.
cnt[i]로 i의 출현 횟수를 기록합니다.
편리하고 같은 숫자가 중복되지 않도록 우리는 각 사람을 순서대로 배열한 상태로 생각한다. 예를 들어 1, 2, 3, 3, 3, 4, 5는 a[i]로 i의 시작 위치를 표시하기 때문에 a[i]개부터 a[i+1]까지 - 1개는 모두 i이다.
다음은 dp의 과정입니다. 첫 번째는 0이 될 수 없기 때문에 특수 처리:
for(int i=1;i<10;i++) { if(cnt[i])dp[1<1~9만 봐도 지금은 한 명의 상황.
다음은 2진법 구성에서 뒤로 미루겠습니다.
for(int i=1;i<(1<
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
long long dp[1<<18][111];
int cnt[11];
int a[11];
string s;
int m;
int main()
{
cin>>s>>m;
int l=s.length();
memset(cnt,0,sizeof(cnt));
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
for(int i=0;i<l;i++)
{
cnt[s[i]-'0']++;
}
for(int i=1;i<11;i++)a[i]=a[i-1]+cnt[i-1];
for(int i=1;i<10;i++)
{
if(cnt[i])dp[1<<a[i]][i%m]=1;
}
for(int i=1;i<(1<<l);i++)
{
for(int j=0;j<m;j++)
{
if(dp[i][j])
{
for(int k=0;k<=9;k++)
{
for(int p=a[k];p<a[k+1];p++)
{
if(i&(1<<p))continue;
dp[i+(1<<p)][(j*10+k)%m]+=dp[i][j];
break;
}
}
}
}
}
cout<<dp[(1<<l)-1][0]<<endl;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
poj 1112 염색약 + DP전송문 제목: n 개인은 2팀으로 나뉘어 최대한 인원수에 가까워야 하며, 동시에 한 팀의 사람들은 서로를 모두 알고 어떻게 나눌지 물어야 한다. 사고방식: 우선 한 그룹의 가장자리를 만들 수 없고 하나하나가 연결되어...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.