您的位置:首页 > 其它

【Hihocoder1636】Pangu and Stones(区间DP)

2018-10-17 21:40 351 查看

题意:N堆石子,每次可以合并连续的长度从L到R的若干堆石子为1堆,费用为选择的石子总个数,求将N堆合并成1堆的最小总花费,无解输出0

思路:dp[i][j][k]表示将i到j这段区间合并为k堆的最小代价

\[ 初始条件   dp[i][j][j-i+1]=0 \]

\[ dp[i][j][k]=min(dp[i][x][y-1]+dp[x+1][j][1]+s[j]-s[i-1]   (k=1,i<=x<=j-1,L<=y<=R) \]

\[ dp[i][j][k]=min(dp[i][x][k-1]+dp[x+1][j][1]   (k>=2,i<=x<=j-1) \]

1 #include<cstdio>
2 #include<cstring>
3 #include<string>
4 #include<cmath>
5 #include<iostream>
6 #include<algorithm>
7 #include<map>
8 #include<set>
9 #include<queue>
10 #include<vector>
11 using namespace std;
12 typedef long long ll;
13 typedef unsigned int uint;
14 typedef unsigned long long ull;
15 typedef pair<int,int> PII;
16 typedef vector<int> VI;
17 #define fi first
18 #define se second
19 #define MP make_pair
20 #define N   150
21 #define M   6100000
22 #define eps 1e-8
23 #define pi  acos(-1)
24 #define oo  1e9
25
26 ll dp


,a
,s
;
27
28 int main()
29 {
30     //freopen("hihocoder1636.in","r",stdin);
31     //freopen("hihocoder1636.out","w",stdout);
32     int n,L,R;
33     while(scanf("%d%d%d",&n,&L,&R)!=EOF)
34     {
35         s[0]=0;
36         for(int i=1;i<=n;i++)
37         {
38             scanf("%lld",&a[i]);
39             s[i]=s[i-1]+a[i];
40         }
41         memset(dp,0x3f,sizeof(dp));
42         for(int i=1;i<=n;i++)
43          for(int j=i;j<=n;j++) dp[i][j][j-i+1]=0;
44         for(int len=2;len<=n;len++)
45          for(int i=1;i<=n-len+1;i++)
46          {
47              int j=i+len-1;
48              for(int x=i;x<=j-1;x++)
49               for(int y=L;y<=R;y++)
50               dp[i][j][1]=min(dp[i][j][1],dp[i][x][y-1]+dp[x+1][j][1]+s[j]-s[i-1]);
51              for(int k=2;k<=len;k++)
52               for(int x=i;x<=j-1;x++)
53                dp[i][j][k]=min(dp[i][j][k],dp[i][x][k-1]+dp[x+1][j][1]);
54          }
55         if(dp[1]
[1]>oo) printf("0\n");
56          else printf("%lld\n",dp[1]
[1]);
57     }
58     return 0;
59 }

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: