P1220 가로등 끄기(구간dp)

1824 단어 re0dp
이 문제는 한참동안 생각한 끝에 한 구간의 가로등을 끄는 마지막 위치가 가장 왼쪽에 있거나 가장 오른쪽에 있는 두 가지 상태이기 때문에 상태를 세운 것을 발견했다. [i, j]는 이 구간의 가로등이 가장 적게 소모되고 0은 가장 왼쪽에 있고 1은 가장 오른쪽에 있다는 것을 의미한다.이 제목에는 또 하나의 구덩이가 있다.while(scanf('%d%d', &n, &s)==2)로 90점까지 쭉 가다가 마지막에 다른 사람의while를 보고 지나가면...땀.
상태 방정식 dp[j][i][0]=min(dp[j+1][i][0]+(x[j+1]-x[j])*(sum[n]-(sum[i]-sum[j]), dp[j+1][i][1]+(x[i]-x[j])*(sum[n]-(sum[i]-sum[j]))))
와 dp[j][i][1]=min(dp[j][i-1][0]+(x[i]-x[j])*(sum[n]-(sum[i-1]-sum[j-1]), dp[j][i-1][1][1]+(x[i]-x[i-1]))*(sum[n]-(sum[i-1]-sum[j-1])))))))))))
sum는 전구 출력의 접두사와 각 구간을 나타낸다. [j,i]는 [j+1,i]와 [j,i-1]만 출시되기 때문에 상태 방정식은 위와 같다.
코드는 다음과 같습니다.
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
const int maxn=1000;
const int inf=99999999;
int n,s;
int dp[maxn][maxn][2]={},x[maxn]={},w[maxn]={},sum[maxn]={};
inline int cime(int x,int y,int x1,int y1){
    return abs(dp[x][y][2]-dp[x1][y1][1]);
}
int main()
{
    scanf("%d%d",&n,&s);
        memset(dp,999,sizeof(dp));
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x[i],&w[i]);
            sum[i]=sum[i-1]+w[i];
        }
        dp[s][s][0]=dp[s][s][1]=0;
        for(int i=s;i<=n;i++)
        for(int j=i-1;j>=1;j--){
            dp[j][i][0]=min(dp[j+1][i][0]+(x[j+1]-x[j])*(sum[n]-(sum[i]-sum[j])),dp[j+1][i][1]+(x[i]-x[j])*(sum[n]-(sum[i]-sum[j])));
            dp[j][i][1]=min(dp[j][i-1][0]+(x[i]-x[j])*(sum[n]-(sum[i-1]-sum[j-1])),dp[j][i-1][1]+(x[i]-x[i-1])*(sum[n]-(sum[i-1]-sum[j-1])));
        }
        printf("%d
",min(dp[1][n][1],dp[1][n][0])); return 0; }

좋은 웹페이지 즐겨찾기