2018.02.04(补作业系列)

Posted yzyl-leo-wey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018.02.04(补作业系列)相关的知识,希望对你有一定的参考价值。

2018.02.04

补作业系列

1.合并石子

思路:

核心代码:

状态转移方程&解析:s[i]表示前i堆石子的数量总和,f[i][j]表示把第i堆石子到第j堆石子合并成一堆的最优值。

1 for ( i = n-1 ; i >= 1 ; i-- ){
2     for ( j = i+1 ; j <= n ; j++ ){
3         for ( k = i ; k <= j-1 ; k++ ){
4             f[i][j] = min ( f[i][j] , f[i][k] + f[k+1][j] + s[j] -s[i-1] );
5         }
6     }
7 }
8 输出f[1][n]

状态:AC

2.挖地雷

思路:

核心代码:

技术分享图片
 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 int main(){
 5     long f[201]={0},w[201],c[201]={0};
 6     int a[201][201]={0}; 
 7     long i,j;
 8     long n;
 9     long x,y;
10     long l,k,maxx;
11     memset(f,0,sizeof(f));
12     memset(c,0,sizeof(c));
13     memset(a,0,sizeof(a));
14     scanf("%d",&n);
15     for(i=1;i<=n;i++)
16         scanf("%ld",&w[i]);
17     for(i=1;i<n;i++){
18         for(j=i+1;j<=n;j++){
19             scanf("%d",&x);
20             if(x==1)a[i][j]=1;
21         }
22     }
23     f[n]=w[n];
24     for(i=n-1;i>=1;i--){
25         l=0;k=0;
26         for(j=i+1;j<=n;j++)
27             if((a[i][j])&&(f[j]>l)){
28                 l=f[j];k=j;
29             }
30         f[i]=l+w[i];
31         c[i]=k;
32     }
33     k=1;
34     for(j=2;j<=n;j++)
35         if(f[j]>f[k])k=j;
36     maxx=f[k];
37     printf("%ld",k);
38     k=c[k];
39     while(k!=0){
40         printf(" %ld",k);
41         k=c[k];
42     }
43     printf("\n%ld\n",maxx);
44     return 0;
45 }
View Code

状态转移方程&解析:

很明显,题目所规定的所有路径都是单向的,所以满足无后效性原则和最优化原理。设w[i]为第i个地窖所藏有的地雷数,a[i][j]表示第i个地窖与第j个地窖之间是否有通路,f[i]为从第i个地窖开始最多可以挖出的地雷数,则有如下递归式:

1 f[i]=max{ w[i]+f[j] }    ( i<j<=n  &&  a[i][j]=true )
2 边界: f[n]=w[n]

于是就可以通过递推的方法,从后面的f(n)往前逐个找出所有的f[i],再从中找出一个最大的即为问题二的解。对于具体走的路径(问题一),可以通过一个向后的链接来实现。

状态:AC

以上是关于2018.02.04(补作业系列)的主要内容,如果未能解决你的问题,请参考以下文章

C#VS快捷键

C#VS快捷键

C#VS快捷键

Atom编辑器折腾记_(15)JS代码片段补全(插件:javascript-snippets)

20165201 课下作业第十周(选做)

第十周作业补做