1.石子合并问题
在一个圆形操场的四周摆放着n堆石子。现要将石子有序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define Ma_x 99999
#define Mi_x 0
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
int n,w[200],dp[200][200],dq[200][200];
//n表示堆数,w表示每队的数量,dp[i][j]表示从第i堆开始合并j堆(包括第i堆)后的最小花费 ,dq表示最大
int sum(int i,int t){//从第i堆开始,t个石堆合,最后一次的合并的花费
int k,s=0,k1;
for(k=i;k<i+t;k++){
k1=k%n;
if(k1==0) k1=n;
s=s+w[k1];
}
return s;
}
void stone_problem()
{
for(int t=2;t<=n;t++){
for(int i=1;i<=n;i++){
dp[i][t]=Ma_x;
dq[i][t]=Mi_x;
for(int k=1;k<t;k++){
dp[i][t]=min(dp[i][t],dp[i][k]+dp[(i+k-1)%n+1][t-k]+sum(i,t));
dq[i][t]=max(dq[i][t],dq[i][k]+dq[(i+k-1)%n+1][t-k]+sum(i,t));
}
}
}
int mini=Ma_x;
int maxi=Mi_x;
for(int i=1;i<=n;i++){//从第几堆石子开始结果最小
mini=min(mini,dp[i][n]);
maxi=max(maxi,dq[i][n]);
}
cout<<"输出合并成一堆的最小花费为:"<<mini<<endl;
cout<<"输出合并成一堆的最小花费为:"<<maxi<<endl;
}
int main(){
cout<<"输入石子的堆数";
cin>>n;
for(int i=1;i<=n;i++){
cin>>w[i];
dp[i][1]=0;//表示合并一堆的花费,没有合并则花费为0
dq[i][1]=0;
}
stone_problem();
}

1万+



被折叠的 条评论
为什么被折叠?



