자갈 합병 문제 집계
2: 체인 합병 은 N 더미 의 모래 를 한 줄 로 배열 하고 그 번 호 는 1, 2, 3,..., N (N < = 100) 이다.모래 더미 마다 일정한 수량 이 있다.이제 N 더 미 를 모래 더미 로 만들어 야 합 니 다.병합 하 는 과정 은 매번 인접 한 모래 두 무 더 기 를 한 무더기 로 쌓 아 올 릴 수 밖 에 없 으 며, 이렇게 N - 1 회 병합 을 거 쳐 한 무더기 가 된다.합 리 적 인 병합 방법 을 찾 아 총 대 가 를 최소 화하 다.사고: 동적 계획 가설 dp [i] [j] 는 i 개 에서 j 개 합병 시의 최소 (최대) 대 가 를 나타 내 면 전달 공식 을 얻 을 수 있다.
dp[i][j]={0mini≤k
코드 는 다음 과 같 습 니 다:
#include
#include
#include
#include
using namespace std;
const int inf = 99999999;
const int N = 300;
int num[N], sum[N], n;
int dpmax[N][N], dpmin[N][N];
int main() {
while(cin>>n) {
int i,j,k,total;
for(i = 0; i < n; i++) {
cin>>num[i];
}
sum[0] = num[0];
for(i = 1; i < n; i++) {
sum[i] = sum[i-1] + num[i];
}
for(i = 0; i < n; i++) {
for(j = i; j < n; j++) {
dpmax[i][j]= -inf;
dpmin[i][j] = inf;
}
}
for(i = 0; i < n; i++) {
dpmax[i][i] = 0;
dpmin[i][i] = 0;
}
for(k = 1; k < n; k++) {//
for(i = 0; i + k < n; i++) {
for(j = i; j < i + k; j++) {
if(i==0) total = sum[i+k];
else total = sum[i+k] - sum[i-1];
dpmax[i][i+k] = max(dpmax[i][i+k], dpmax[i][j] + dpmax[j+1][i+k] + total);
dpmin[i][i+k] = min(dpmin[i][i+k], dpmin[i][j] + dpmin[j+1][i+k] + total);
}
}
}
int resmax = dpmax[0][n-1];
int resmin = dpmin[0][n-1];
cout<"
"<return 0;
}
3: 환형 판이 돌 이 원형 으로 배열 되 어 있 고 나머지 조건 이 변 하지 않 는 다 면 가장 좋 은 값 은 무엇 일 까?
사고: 원형 이 서로 연결 되 어 있 기 때문에 모든 요 소 를 기점 으로 길이 가 n 인 n 개의 체인 문제 에 해당 합 니 다. 따라서 이 문 제 는 두 가지 해법 이 있 습 니 다. 1. 체인 을 뜯 어서 크기 가 2 * n 인 배열 을 설정 하고 값 은 1. n. 1. n 입 니 다. 그러면 하나의 체인 문 제 를 구성 할 수 있 습 니 다. 2. 동적 계획 중의 dp 의 의 미 를 바 꿀 수 있 습 니 다. 우 리 는 먼저 첫 번 째, dp 의 공식 과 체인 식 을 토론 합 니 다.같 지만 결 과 는 다 릅 니 다. 코드 는 다음 과 같 습 니 다.
#include
#include
#include
#include
using namespace std;
const int inf = 99999999;
const int N = 300;
int num[N], sum[N], n;
int dpmax[N][N], dpmin[N][N];
int main() {
while(cin>>n) {
int i,j,k,total;
for(i = 0; i < n; i++) {
cin>>num[i];
num[i+n] = num[i]; //
}
sum[0] = num[0];
for(i = 1; i < 2*n; i++) {
sum[i] = sum[i-1] + num[i];
}
for(i = 0; i < 2 * n; i++) {
for(j = i; j < 2 * n; j++) {
dpmax[i][j]= -inf;
dpmin[i][j] = inf;
}
}
for(i = 0; i < 2 * n; i++) {
dpmax[i][i] = 0;
dpmin[i][i] = 0;
}
for(k = 1; k < n; k++) {//
for(i = 0; i + k < 2 * n; i++) {
for(j = i; j < i + k; j++) {
if(i==0) total = sum[i+k];
else total = sum[i+k] - sum[i-1];
dpmax[i][i+k] = max(dpmax[i][i+k], dpmax[i][j] + dpmax[j+1][i+k] + total);
dpmin[i][i+k] = min(dpmin[i][i+k], dpmin[i][j] + dpmin[j+1][i+k] + total);
}
}
}
int resmax = -inf;
int resmin = inf;
for(i = 0; i + n - 1 < 2 * n; i++) {//
resmax = max(resmax,dpmax[i][i+n-1]);// n
resmin = min(resmin,dpmin[i][i+n-1]);// n
}
cout<"
"<return 0;
}
주의: 순환 할 때 길 이 는 1 에서 n 까지 이 고 마지막 결 과 는 모든 요소 가 기점 길이 가 n 의 가장 작은 값 중 가장 작은 것 입 니 다.
사고 2: dp [i] [j] 를 설정 하면 i 부터 길이 가 j 의 한 단락 이 합 쳐 진 후의 최소 (최대) 값 을 나타 낸다. 그러면 j 의 최대 n 은 다음 과 같다.
dp[i][j]={0min{dp[i][k]+dp[(i+k+1)%n][j−k−1]+sum(i,j)}j=00≤k
sum[i][j]=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪∑k=ijstone[k]∑k=in−1stone[k]+∑k=0(i+j)%nstone[k]i+j
코드 는 다음 과 같 습 니 다:
#include
#include
#include
using namespace std;
const int inf = 99999999;
const int N = 300;
int dpmin[N][N];
int dpmax[N][N];
int sum[N], a[N];
int resmin, resmax;
int n;
int getsum(int i, int len) // i len
{
if(i + len >= n) return getsum(i,n-i-1) + getsum(0,(i+len) % n);
else return sum[i+len] - (i > 0 ? sum[i-1] : 0);
}
void func(int a[], int n)
{
for(int i = 0; i < n; i++)
dpmin[i][0] = dpmax[i][0] = 0;
for(int j = 1; j < n; j++)
{
for(int i = 0; i < n; i++)
{
dpmin[i][j] = inf;
dpmax[i][j] = -inf;
for(int k = 0; k < j; k++)
{
dpmin[i][j] = min(dpmin[i][j], dpmin[i][k] + dpmin[(i+k+1) % n][j - k - 1] + getsum(i,j));
dpmax[i][j] = max(dpmax[i][j], dpmax[i][k] + dpmax[(i + k + 1) % n][j - k - 1] + getsum(i,j));
}
}
}
resmin = dpmin[0][n-1];
resmax = dpmax[0][n-1];
for(int i = 0; i < n; i++)
{
resmin = min(resmin, dpmin[i][n-1]);
resmax = max(resmax, dpmax[i][n-1]);
}
}
int main()
{
freopen("input.txt","r",stdin);
scanf("%d",&n);
for(int i = 0; i < n; i++)
{
scanf("%d",&a[i]);
}
sum[0] = a[0];
for(int i = 1; i < n; i++)
{
sum[i] = sum[i-1] + a[i];
}
func(a,n);
printf("%d %d
", resmin,resmax);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
제11회 산동성 대학생 프로그램 설계 경연대회 Adventurer's Guild(dp)전송문 제목: 몬스터의 수량 n, 캐릭터의 생명력 H, 캐릭터의 공격 S 건네기;다음 n행, 매 행위 매 몬스터의 혈액량 h, 공격 s, 가치 w; 매번 몬스터를 처치할 때마다 h의 혈액량과 s의 공격을 소모한다. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.