• hdu 5800 To My Girlfriend(背包变形)


    To My Girlfriend

    Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1326    Accepted Submission(s): 515


    Problem Description
    Dear Guo
    I never forget the moment I met with you.You carefully asked me: "I have a very difficult problem. Can you teach me?".I replied with a smile, "of course"."I have n items, their weight was a[i]",you said,"Let's define f(i,j,k,l,m) to be the number of the subset of the weight of n items was m in total and has No.i and No.j items without No.k and No.l items.""And then," I asked.You said:"I want to know
    i=1nj=1nk=1nl=1nm=1sf(i,j,k,l,m)(i,j,k,laredifferent)

    Sincerely yours,
    Liao
    Input
    The first line of input contains an integer T(T15) indicating the number of test cases.
    Each case contains 2 integers ns (4n1000,1s1000). The next line contains n numbers: a1,a2,,an (1ai1000).
     
    Output
    Each case print the only number — the number of her would modulo 109+7 (both Liao and Guo like the number).
    Sample Input
    2 4 4 1 2 3 4 4 4 1 2 3 4
     
    Sample Output
    8 8
     
    Author
    UESTC
     
    Source
    Recommend
    wange2014   |   We have carefully selected several similar problems for you:  6032 6031 6030 6029 6028 
     
    题解:

    就是给你 n个数 其中(序号i,j)是必选的,(序号k,l)是必不选的.使得其中的子集在n个数中的总权值为m. 
    例如样例 
    f(1,2,3,4)=1 f(2,1,3,4)=1 f(1,3,2,4)=1 f(3,1,2,4)=1 
    f(1,2,4,3)=1 f(2,1,4,3)=1 f(1,3,4,2)=1 f(3,1,4,2)=1 所以答案为8.

    个人感想: 
    看了一下题目,我基本没什么思路,然后喵了一下题解,说是dp,然后我想了一个晚上..我觉得自己真是弱鸡,还是没怎么想到,看了网上题解,可以推出朴素的O(n^3)算法,我尼玛我一点感觉也没,我都不知道怎么推出朴素了..我反而悟出了这道题的前2维的计数,但是我就想不到怎么把必选不选的排掉.很烦躁
    然后还是看了一下转载了.但是我就想不通最后两维,好艰难啊. 
    今天早上还是琢磨了一下,我才把它弄懂.

    se->select. 
    dp[i][j][se][nse] 代表 前i个数,和为j,有se个数必选,有nse个必不选的方案数
    是不是很凌乱.我们一步步来,先想前2维.我到不知道为什么别人数是个背包,千万别和背包混一起,我感觉会走弯路,不过确实也类似了.

    我的开始是这样想的. 
    首先 dp[i][j].前i个数和为j,对于当前这个数,如果选择了,就得+dp[i-1][j-a[i]],这时如果不选,+dp[i-1][j].这个先想明白. 
    然后再想到第3维(第4维也是类似). 
    dp[i][j][1]+=dp[i-1][j][1] ,首先前[i-1]个数和为j的方案数,而且其中有1个是必选了,但没有选a[i]
    dp[i][j][1]+=dp[i-1][j-a[i]][1],首先前[i-1]个数和为j的方案数,而且其中有1个是必选了,,但选了a[i].a[i],不是必选的
    dp[i][j][1]+=dp[i-1][j-a[i]][0],首先前[i-1]个数和为j的方案数,而且其中有1个是必选了,,选了a[i].a[i]是必选的
    这样理解应该懂了吧,其中1维也是这样的思想..这就推出来了几种必选必不选的方案数了.

    分析: 计数dp. 

    转载:http://blog.csdn.net/zzz805/article/details/52135094

    #include <bits/stdc++.h>
    
    using namespace std;
    const int mod=1e9+7;
    int dp[1005][1005][3][3];
    int n,s,T;
    int a[1005];
    int main()
    {
        scanf("%d",&T);
        for(;T>0;T--)
        {
            scanf("%d%d",&n,&s);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            memset(dp,0,sizeof(dp));
            dp[0][0][0][0]=1;
            for(int i=1;i<=n;i++) //前i件物品
                for(int j=0;j<=s;j++)  //背包当前容量为j
                 for(int x=0;x<=2;x++) //dp[i][j]x][y]中有x个物品是属于必选的
                   for(int y=0;y<=2;y++) //dp[i][j][x][y]中有y个物品是属于不能选的
            {
                dp[i][j][x][y]=(dp[i][j][x][y]+dp[i-1][j][x][y])%mod; //第i件item不选
                if (y-1>=0) dp[i][j][x][y]=(dp[i][j][x][y]+dp[i-1][j][x][y-1])%mod;
                if (j-a[i]>=0)
                {
                    dp[i][j][x][y]=(dp[i][j][x][y]+dp[i-1][j-a[i]][x][y])%mod;
                    if (x-1>=0) dp[i][j][x][y]=(dp[i][j][x][y]+dp[i-1][j-a[i]][x-1][y])%mod;
                }
            }
          long long ans=0;
          for(int j=1;j<=s;j++) ans=(ans+dp[n][j][2][2])%mod;
          ans=(ans*4)%mod;
          printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    上传高德地图-express框架
    express不是内部命令
    elasticSearch 安装
    elasticSearch 分布式安装
    mongoDB基本操作
    [是题解哦] 洛谷 P1865 A % B Problem
    [是题解哦] 洛谷 P1531 I Hate It
    [是题解哦] 洛谷 P1195 口袋的天空
    [是题解哦] 洛谷 P1536 村村通
    [是模板哦] 快速读入
  • 原文地址:https://www.cnblogs.com/stepping/p/7156153.html
Copyright © 2020-2023  润新知