vijos P1071

来源:互联网 发布:单片机ds18b20 编辑:程序博客网 时间:2024/06/11 17:00

学习动态规划的时候碰到的一点问题:就是把一些经典的问题转化为背包问题的思考方向,就是数学上所说的数学建模。

Link:http://www.vijos.cn/Problem_Show.asp?id=1071

这道题,刚刚开始看到的时候,就想到用搜索算法来计算(这个可以尝试去做,后期我会写)

要注意只有当前状态没有方案时才记录当前的方案,否则会把正确方案替换了。这是为什么呢?这就要讨论到一维背包问题中的最优解正确,但是方案不正确,在本文章总不做解释。

Code:

#include<stdio.h>#include<climits>#include<algorithm>#include<stack>#include<iostream>#include<cmath>#include<set>#include<vector>#include<map>#include<queue>#include<string.h>using namespace std;const int maxn=500;int opt[maxn],ans[maxn],path[maxn];int a[maxn];//用来记录的是当前的数组 int  main(void){ int n,total; while(scanf("%d %d",&total,&n)!=EOF) {    for(int i=1;i<=n;i++)    { scanf("%d",&a[i]);}//读入数据 memset(opt,0,sizeof(opt));//用来记录的是选择的方案 memset(ans,0,sizeof(ans));//用来记录的是最终的结果 memset(path,0,sizeof(path));//用来记录路径的opt[0]=1; for(int i=1;i<=n;i++)//这两个循环是背包问题的一维状态,可以参考背包九讲 {  for(int j=total;j>=a[i];j--)  {     if(opt[j-a[i]]>0)     {    if(path[j]==0)//当前方案不存在的时候就选择       path[j]=i;          opt[j]+=opt[j-a[i]];     }  }}if(opt[total]==0)//没有方案 {      printf("0\n");      continue;    } if(opt[total]>1)//不止一个方案 {           printf("-1\n");           continue;        }        int i=total;        while(i>0)//求出选择的发难         {           ans[path[i]]=1;//把组成当前方案的前一个元素设置为存在            i-=a[path[i]];        }        for(int j=1;j<=n;j++)//输出结果         {  if(ans[j]!=1)//这张牌不存在的话就输出      printf("%d ",j);} }   return 0;}

输出:

270
4
100
110
170
200
2 4

0 0
原创粉丝点击