이모저모

1514 본문

BOJ/DP

1514

Alpa 2017. 5. 2. 16:31




시도1.


dp[p][np][npp] : 현재 위치가 p일때 p+1 가 np만큼 움직였고,  p+2가  npp만큼 움직인 상황에서 최소 횟수 p 위치에서 위 또는 아래로 1,2,3개를 같이 움직여서 p위치에 원하는 값을 맞추고 다음 p+1로 움직인다하지만 p 위치에서 1개를, 2개를, 3개를 조합해서 돌릴 경우가 존재할 수 있으며 위에는 그 경우의 수를 포함하지 않는다.

해결방법

dp[p][m1][m2][m3] : 위치가 p일때 p,p+1,p+2 위치에 대해 움직임이 m1,m2,m3 일때 최소 이동 횟수 위의 문제를 해결하기 위해 조합을 통해서 문제를 풀수 있게 바로 p+1로 움직이는게 아니라 1~9까지 움직여 보는 것이다.


dp를 적용할 때는 모든 경우의 수를 포함할 수 있는지 꼭 점검해야 겠다.!!(물론 답을 찾기 위해 필요한 것들만)





#include <iostream> 

#include <iterator>

#include <algorithm> 

#include <vector>

#include <list>

#include <map>

#include <set>

#include <queue>

#include <stack>

#include <string>

#include <cmath>

#include <cstdio>

#include <cstring>

using namespace std;

#define MOD 1000000007

#define INF 2147483647

#define LNF 9223372036854775807



int n,in[100],out[100],dp[100][10][10][10],cal[10]={0,1,1,1,2,2,2,1,1,1};

int solve(int p, int m1, int m2, int m3){

if(p==n) return 0;

int &ret = dp[p][m1][m2][m3];

if(ret != -1) return ret;

ret = 100000;

if((in[p]+m1)%10==out[p]) ret=solve(p+1,m2,m3,0);

for(int i=1; i<10; i++){

ret = min(ret, solve(p,(m1+i)%10,m2,m3)+cal[i]);

ret = min(ret, solve(p,(m1+i)%10,(m2+i)%10,m3)+cal[i]);

ret = min(ret, solve(p,(m1+i)%10,(m2+i)%10,(m3+i)%10)+cal[i]);

}

return ret;

}

int main () {

freopen("sample.txt", "r", stdin);

scanf("%d",&n);

char ch[101];

scanf("%s",ch);

for(int i=0;i<n;i++) in[i]=ch[i]-'0';

scanf("%s",ch);

for(int i=0;i<n;i++) out[i]=ch[i]-'0';

memset(dp,-1,sizeof(dp));

printf("%d\n",solve(0,0,0,0));

return 0;

}

'BOJ > DP' 카테고리의 다른 글

14585  (0) 2017.05.22
14578  (0) 2017.05.17
2579  (0) 2017.05.12
2213  (0) 2017.05.03
10272  (0) 2017.04.27
Comments