[poj 1191] 바둑판 분할 DP
9133 단어 dppoj출제 기록을 갱신하다.
Description은 8*8의 바둑판을 다음과 같이 분할한다. 원 바둑판을 직사각형 바둑판으로 잘라서 나머지 부분도 직사각형으로 만들고 나머지 부분을 계속 이렇게 분할한다. 이렇게 (n-1)번 잘라낸 후에 마지막 남은 직사각형 바둑판과 함께 n개의 직사각형 바둑판이 있다.(각 컷은 검사기의 모서리를 따라만 가능)
원 바둑판에 있는 한 칸마다 점수가 하나 있고, 직사각형 바둑판의 총점은 그 안에 포함된 각 칸의 점수의 합이다.현재 바둑판을 상술한 규칙에 따라 n개의 직사각형 바둑판으로 나누고 각 직사각형 바둑판의 총점의 균일 방차를 최소화해야 한다.균방차, 그 중에서 평균치는 xi가 i개의 직사각형 바둑판의 총점이다.주어진 바둑판과 n을 프로그래밍해서 O의 최소값을 구하십시오.
Input 첫 번째 동작은 정수 n(1 < n < 15)입니다.두 번째 줄에서 아홉 번째 줄까지 행위당 100보다 작은 8개의 비음정수는 바둑판에 있는 상응하는 칸의 점수를 나타낸다.줄마다 인접한 두 수 사이를 빈칸으로 구분하다.
Output은 O"(반올림은 소수점 아래 세 자리까지 정확함)입니다.
Sample Input
3 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 3
Sample Output
1.633
Source Noi 99
제목 링크:http://poj.org/problem?id=1191;
제목: 중국어 문제는 여러분들이 알아볼 수 있겠지요...
사고방식: 공식: 균일치가 일정하다.S2=1/n∑(Xi−X)2==1/n∑Xi2−X2;
DP 분할;1.예처리: i블록의 점수;2.dp[k][x1][y1][x2][y2]는 직사각형의 k회 구분의 최소 대가를 나타낸다.귀속 처리(매거 직사각형 내의 가로 절단과 세로 절단);
코드:
#include
#include
#include
#include
using namespace std;
int ma[9][9];
int n;
int sum[9][9][9][9];
int dp[16][9][9][9][9];
void init()
{
for(int x=0;x<8;x++)
for(int y=0;y<8;y++)
for(int xx=x;xx<8;xx++)
for(int yy=y;yy<8;yy++)
{
int ans=0;
for(int i=x;i<=xx;i++)
for(int j=y;j<=yy;j++)
ans+=ma[i][j];
sum[x][y][xx][yy]=ans*ans;
//cout<<x<<" "<<y<<" "<" "<" "<x][y][xx][yy]<int DP(int k,int x,int y,int xx,int yy)
{
if(dp[k][x][y][xx][yy]>=0) return dp[k][x][y][xx][yy];
if(k==n-1)return sum[x][y][xx][yy];
int ans=0;
dp[k][x][y][xx][yy]=1<<29;
for(int i=x;i1,x,y,i,yy)+sum[i+1][y][xx][yy],DP(k+1,i+1,y,xx,yy)+sum[x][y][i][yy]);
dp[k][x][y][xx][yy]=min(ans,dp[k][x][y][xx][yy]);
}
for(int i=y;i<=yy;i++)
{
ans=min(DP(k+1,x,y,xx,i)+sum[x][i+1][xx][yy],DP(k+1,x,i+1,xx,yy)+sum[x][y][xx][i]);
dp[k][x][y][xx][yy]=min(ans,dp[k][x][y][xx][yy]);
}
//cout<x][y][xx][yy]<return dp[k][x][y][xx][yy];
}
int main()
{
double ans;
scanf("%d",&n);
int cnt=0;
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
scanf("%d",&ma[i][j]);
cnt+=ma[i][j];
}
}
init();
memset(dp,-1,sizeof(dp));
DP(0,0,0,7,7);
ans=sqrt(dp[0][0][0][7][7]*1.0/n-(cnt*1.0)/n*(cnt*1.0)/n);
//cout<0][0][0][7][7]*1.0/n<<" "<*1.0/n*(cnt*1.0)/n<//cout<printf("%.3f
",ans);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.