算法程序设计杂谈

1.并查集:数组并查,高效的判断数据是否在同一集合,套用代码模板即可。

                 递归调用find(x);循环归并Merge(a,b);fd[a]=b;

2.背包问题:分为0-1背包,完全背包,多重背包 问题。

                     使用动态规划,代码简介,功能强大,需要较多的时间去理解思考。也是计算机科学与程序设计神奇魅丽所在。

                     计算转移方程,推荐二维数组,理解方便。背包问题在二维数组中转换。

                     可以压缩成一维滚动数组,计算好利用的存储位置,进行压缩。

        有N件物品装入容量为V的背包。第i件物品费用是w[i],价值是p[i],求解不超过背包容量的最大价值。

                     转移方程:f[i][v]=max{f[i-1][v],f[i-1][v-w[i]]+p[i]};

                     压缩一维:for(int i=1;i<=n;i++) for(int v=V;v>=w[i];--v) f[v]=max(f[v],f[v-w[i]]+p[i]);   cout<<f[V]<<endl;

3.果园里有水果若干堆,现将所有水果合并成一堆。每一次合并,可以将两堆水果合并到一起,消耗的体力等于两堆水果重量之和。经过N-1次合并后,变成一堆。合并时消耗的体力等于每次合并消耗的体力之和。求设计出合适的合并次序方案,计算使得合并消耗体力之和最小。

假定每个水果重量均为1,如果有3堆水果,数目依次为1,2,9.可以先将1,2堆合并,耗费体力为3,再与第三堆合并,耗费体力为12,共耗费体力3-12-15.可以证明,15为最小体力耗费值。

水果堆数<=10000,每堆数目<=10000;  

解法:贪心+最小堆

priority_quequ < int , vector <int>, greater <int> > q;

优先队列,最高优先级总是第一个出队列。greater:从小到大 

4.动态规划=递归+中间计算保存 or 递推

吉哥一共有m天的假期,每天的编号从1到m,一共有n份可以做的工作,每份工作都知道起始时间s,终止时间e和对应的工资c,每份工作的起始和终止时间以天为单位(即天数编号),每份工作必须从起始时间做到终止时间才能得到总工资c,且不能存在时间重叠的工作。比如,第1天起始第2天结束的工作不能和第2天起始,第4天结束的工作一起被选定,因为第2天吉哥只能在一个地方工作。
  现在,吉哥想知道怎么安排才能在假期的m天内获得最大的工资数(第m+1天吉哥必须返回学校,m天以后起始或终止的工作是不能完成的)。

Input:第一行是数据的组数T;每组数据的第一行是2个正整数:假期时间m和可做的工作数n;接下来n行分别有3个正整数描述对应的n个工作的起始时间s,终止时间e,总工资c。

动归:dp[i]表示到今天所能挣到的最多的钱,dp[i]= MAX(dp[i],dp[j]+a[j+1][i]);其中a[i][j]:从第i天到j天的工资。

int iHoliday,iWorks,iStart,iEnd,iSalary;

int iWorkDay[MAXN][MAXN];

int dp[MAXN];

for(int i=0;i<iWorks;++i)

{

          scanf(&iStart,&iEnd,&iSalary);

          if(iStart>iHoliday || iEnd > iHoliday) continue;

          if(iSalary>iWorkDay[iStart][iEnd])  iWorkDay[iStart][iEnd] = iSalary;
}

for(int i=1;i<= iHoliday;++i)

{

     for(int j=0;j<i;++j) 

           dp[i]=MAX(dp[i],dp[j]+iWorkDay[j+1][i]);

}

5.

工作室是一个N行M列的矩形布局,小Q暗自给每个同事进行了评分(为区别男女,男生一律用负整数,女生一律用正整数)。
现在,小Q把所有人的数据记录下来,并且这样定义一个位置的价值:
1、一个位置的价值只和其上下左右四个邻居的魅力值有关(对于靠边的位置,只考虑其存在的邻居);
2、如果某位置的邻居和该位置主人性别不同,则总分加上邻居魅力值的绝对值,否则减去;
3、对周围所有邻居的数据处理后,最终的得分即为这个位置的最终得分,得分越高,则该位置越好;

计算一下最佳位置?
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值