uva 10817 紫书 例9-15



谈一下自己对dp的想法。

dp的感觉就分两种  1.模拟,根着题目的意思一个个选择(dfs);就像本题一个个选择老师;

                                   2.大化小,紫书习题3 切蛋糕,和习题4 flod 字符串,就好。

dp的状态,就像函数里的自变量,dp的值就像函数的自变量。


剩下的紫书就讲的很详细了


//uva 10817
//紫书 第9章 例15
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<sstream>
#include<cstring>
#include<string>
using namespace std;
const int maxn=100+25;
const int inf =0x3f3f3f3f;
int p[maxn];
int ret[maxn];
int s,n,m;
int N;
int dp[1<<10][1<<10][maxn];

int dfs(int s0,int s1,int s2,int pos)
{
    if(pos==N)
    {
       return s2==(1<<s)-1 ? 0:inf;
    }

    if(dp[s1][s2][pos]!=-1)
    {
        return dp[s1][s2][pos];
    }

    dp[s1][s2][pos]=inf;
    if(pos>=m)
    dp[s1][s2][pos]=dfs(s0,s1,s2,pos+1);

    //if(pos>=m)
    //
        int m0,m1;
        m0=s0&ret[pos];
        m1=s1&ret[pos];
        int t0,t1,t2;
        t0=s0^m0;
        t1=s1^m1|m0;                                  /*akfjcasjk*/
        t2=s2|m1;
        dp[s1][s2][pos]=min(dp[s1][s2][pos],dfs(t0,t1,t2,pos+1)+p[pos]);
    //}

    return dp[s1][s2][pos];
}
int main()
{
    string str;
   // printf("%d\n",inf);
    while(scanf("%d",&s)!=EOF)
    {
        if(s==0) break;
        scanf("%d %d",&m,&n);
        if(s==0 && m==0 && n==0) break;
        N=n+m;

        for(int i=0;i<N;i++)
        {
//re[i].clear();

            scanf("%d",&p[i]);

            getline(cin,str);
            stringstream s(str);

            int t;
            ret[i]=0;
            while(s>>t)
            {
                t--;
                ret[i]=ret[i]|(1<<t);
            }
            //cout<<ret[i]<<endl;
        }

//        for(int i=0;i<n+m;i++)
//        {
//            for(int j=0;j<re[i].size();j++)
//            {
//                cout<<re[i][j]<<" ";
//            }
//            cout<<endl;
//        }
          memset(dp,-1,sizeof(dp));
        int ans=dfs((1<<s)-1,0,0,0);
        printf("%d\n",ans);
      //  cout<<m<<n<<endl;
    }
    return 0;
}


//很经典的一题
























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值