ZOJ 3777(状压DP)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777

 

题目大意:有n道题,每道题被安排在不同的位置有不同的值,求安排结果>=m在所有结果中的比例

 

题目思路:很明显的状压DP,但是>=m需要转换。由于m范围很小,所以可以想到为它多开一维,dp[i][j],i表示状态,j表示值。一个数字的二进制表示选题状态,从1~1^n-1正好可以全部表示,而且后面的一定可以由前面的转换而来。转换也很简单,对于i中每一位进行遍历,遇到1就说明这位有,说明可以从没有这位的情况转过来,而这一位可以作为现在才加入这个状态,也就是i中1的数量就是他被放入的位置,这样就可以得到现在放入这道题会得到多少价值,然后从0~m所有价值+他的价值进行转移,如果>=m就压到m即可。

 

以下是代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
using namespace std;
const int MAXN = 1e4+10;
int n,m,a[20][20],dp[MAXN][505];
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        rep(i,1,n){
            rep(j,1,n){
                scanf("%d",&a[i][j]);
            }
        }
        int endd=(1<<n)-1;
        dp[0][0]=1;
        rep(i,1,endd){
            int tnt=0;
            rep(j,1,n){
                int temp=1<<(j-1);
                if(temp&i){
                    tnt++;
                }
            }
            rep(j,1,n){
                int temp=1<<(j-1);
                if(temp&i){
                    rep(k,0,m){
                        int pp=min(m,k+a[j][tnt]);
                        dp[i][pp]+=dp[i-temp][k];
                    }

                }
            }
        }
        if(dp[endd][m]==0){
            printf("No solution\n");
        }
        else{
            int aint=1;
            rep(i,2,n)aint*=i;
            int x=gcd(dp[endd][m],aint);
            printf("%d/%d\n",aint/x,dp[endd][m]/x);
        }
    }
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值