题意:【浙江省赛】

给定n、m。有n个物品,进行全排列,然后p[i][j]表示第i个物品放在第j个位置所能得到的价值,现在开始对n个物品进行任意摆放,求第一次摆出一个排列,该排列的总价值大于或等于m的期望次数。

思路:

看到这题就回想起了之前做过的一个状压dp题目,12根木头,求最多能够摆出多少个三角形,于是从状压dp的角度切入思考这道题目。首先求期望次数就是求一共有多少种排列方式可以满足题意,然后总排列次数 / 期望次数就是答案了。

然后我们来思考如何dp,我一开始想的是,dp[i][S]表示前i个物品,选择状态是S,此时的最大价值。然后发现这种dp方式没有办法解决价值大于m的总排列个数问题,因此考虑再加一维dp[i][S][k],表示前i个物品,选择状态是S,此时价值为k的总方案数。这样就可以进行dp了,由于dp[i]只与dp[i-1]有关,因此压缩一维,三维循环。

由于担心会TLE,因此需要进行一下优化,首先处理出S中有x个1的所有状态数,这样在第二层循环的时候,就可以直接对这些状态数进行循环,而不是循环整个S。再优化第三维,求出前i个元素在各个位置最大值相加的值,这个值就是k的上限,而不是直接循环到1200,这样就可以大量减少时间,通过此题。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;
const int N = 6000;int base[15][N], pos[N][15], mi[15];  //base[i][0]表示有i个1的状态总共有多少个
//pos[i]表示数字i的1分别在哪几个位置, mi[i]表示2^i
int n,m,ans;
int val[15][15],dp[N][1500], minn[15], maxn[15], sum[15];
//dp[i][S][k]表示前i个点, 选择情况为S, 总价值为k的方案数
//minn[i]表示第i行最小的数int gcd(int a,int b)
{return b == 0 ? a:gcd(b,a%b);
}void init()
{base[0][0] = 1;base[0][1] = 0;rep(i,1,(1<<12)-1){int cnt = 0;int tp = i;int hm = 0;while(tp){hm++;if(tp&1){cnt++;pos[i][cnt] = hm;} tp /= 2;}int num = ++base[cnt][0];base[cnt][num] = i;}mi[1] = 1;rep(i,2,12)mi[i] = mi[i-1]*2;
}   void solve()
{rep(i,0,5000)rep(j,0,1200) dp[i][j] = 0;ans = 0;rep(i,1,base[1][0]){if(base[1][i] > ((1<<n)-1)) break;int gn = pos[base[1][i]][1];dp[base[1][i]][val[1][gn]] = 1;}rep(i,2,n)rep(j,1,base[i][0])   //base[i][0]表示有i个1的状态总共有多少个{if(base[i][j] > ((1<<n)-1)) break;rep(k,minn[i],sum[i]){int vu = base[i][j];  //1的个数为i个的状态数dp[vu][k] = 0;rep(h,1,i){ //有i个1int ph = pos[vu][h]; //1所在的位置dp[vu][k] += dp[vu-mi[ph]][k-val[i][ph]];    }}}rep(i,m,1200)ans += dp[(1<<n)-1][i];if(ans == 0)printf("No solution\n");else{int tp = 1;rep(i,1,n){tp *= i;}int hm = gcd(tp,ans);printf("%d/%d\n",tp/hm,ans/hm);}
}int main()
{init();int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);sum[1] = 0;rep(i,1,n){minn[i] = 1000;maxn[i] = -1;rep(j,1,n){scanf("%d",&val[i][j]);minn[i] = min(minn[i],val[i][j]);maxn[i] = max(maxn[i],val[i][j]);}sum[i] = sum[i-1]+maxn[i];}solve();}return 0;
}

题意:【CCPC-Wannafly】

给出12根木棒,求一共可以拼出多少个三角形。并输出选取的木棒。

思路:

本题与上面浙江省赛的题目类似,不过本题只需要求最大值,因此可以减少一维。

首先先将所有木棒的长度进行排序,这样判断是否能够拼接成三角形的时候,就只需要判断两个小的相加是否比大的大了。先处理出所有1的个数是三的倍数的数,然后循环这些数。dp[S]表示选取状态为S时能够拼出的最多的三角形个数,然后三重循环枚举S中的3个1的位置。然后减去三个1之后的状态x,查看dp[x]是否可以更新dp[S],即可完成dp过程。dp过程中还需要记录dp[i]的前驱,即pre[i],最后输出选取方案的时候,按照pre进行输出即可。

总结一下两题,本题是求选取方案的最大值,并且输出选取方式。上一题是输出一共有多少个符合题意的结果,因此多加了一维表示当前方案下的价值。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;int a[15];
int base[6000][20];
int n;
int pos[6000], dp[6000], pre[6000];void solve()
{n = 0;rep(i,1,(1<<12)-1){int ct = 0;n++;rep(j,0,12){if(i&(1<<j)) ct++, base[n][ct] = j;}if(ct%3) n--; else base[n][0] = ct, base[n][++ct] = i, pos[i] = n;}
}int main()
{int T;scanf("%d",&T);int li = 1;solve();while(T--){memset(dp,0,sizeof dp);rep(i,0,11) scanf("%d",&a[i]);sort(a,a+12);int ans = 0, ansp;rep(i,1,n)   //对所有1的个数是3的倍数的数字进行循环{int cnt = base[i][0];    //base[i]存储了数i中各个1的位置// printf("num:%d\n",base[i][cnt+1]);rep(j,1,cnt)   //循环i中的三个1,看是否可以更新dp[i]rep(k,j+1,cnt)rep(hp,k+1,cnt)if(a[base[i][hp]] < a[base[i][j]]+a[base[i][k]]){int ht = base[i][cnt+1]-(1<<base[i][j])-(1<<base[i][k])-(1<<base[i][hp]);// printf("ht:%d\n",ht);if(ht == 0) dp[i] = 1, pre[i] = 0;else{if(dp[pos[ht]]+1 > dp[i]) dp[i] = dp[pos[ht]]+1, pre[i] = pos[ht];}if(dp[i] > ans) ans = dp[i], ansp = i;}//假如i为6个1的一个数,则能够更新i的dp[x],x < i,因此dp[x]一定已经求出来了,所以这种解法正确}printf("Case #%d: %d\n",li++,ans);if(ans > 0){while(ansp){int ct1 = base[ansp][0], ct2 = base[pre[ansp]][0];int tp1 = base[ansp][ct1+1], tp2;if(pre[ansp] == 0) tp2 = 0;else{tp2 = base[pre[ansp]][ct2+1];}int tp3 = pos[tp1-tp2];int ct3 = base[tp3][0];rep(i,1,ct3){printf("%d",a[base[tp3][i]]);if(i == ct3) printf("\n");else printf(" ");}ansp = pre[ansp];}}}return 0;
}

【14浙江省赛 B ZOJ 3777】Problem Arrangement 【状压dp】 【CCPC-Wannafly Winter Camp Day2 K Sticks】相关推荐

  1. ZOJ - 3777 Problem Arrangement(状压dp)

    题目链接:点击查看 题目大意:给出n道题,以及不同题目不同时间的兴趣值,p[i][j]代表的是第j道题放在第i个位置做的时候可以得到的兴趣值,问有多少种排列组合的方式能让最后做完所有题目的兴趣值大于等 ...

  2. YbtOJ#20239-[冲刺NOIP2020模拟赛Day10]连边方案【状压dp】

    正题 题目链接:https://www.ybtoj.com.cn/contest/68/problem/3 题目大意 求有多少个nnn个点mmm条边的无向图满足 有连边的点之间编号差不超过kkk 所有 ...

  3. FZU2218 Simple String Problem(状压DP)

    首先,定义S,表示前k个字符出现的集合,用二进制来压缩. 接下来,推出dp1[S],表示集合为S的子串的最长长度. 然后根据dp1[S]再推出dp2[S],表示集合为S或S的子集的子串的最长长度. 最 ...

  4. ZOJ 3755 - Mines (状压DP)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5178 题意: 大家都玩过扫雷吧. 给你n*m的扫雷数字.数字都在偶数列上. 也 ...

  5. 第九届河南省赛 宣传墙 //状压dp+矩阵快速幂+dfs

    http://nyoj.top/problem/1273 状压dp+矩阵快速幂+dfs 1273-宣传墙 内存限制:64MB 时间限制:1000ms 特判: No 通过数:19 提交数:64 难度:4 ...

  6. nyoj1273 河南省第九届省赛_宣传墙、状压DP+矩阵幂加速

    宣传墙 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 ALPHA 小镇风景美丽,道路整齐,干净,到此旅游的游客特别多.CBA 镇长准备在一条道路南 面 4*N 的墙上做 ...

  7. 糖果(2019第十届蓝桥杯省赛C++A组I题) 解题报告(状压dp) Apare_xzc

    糖果(2019第十届蓝桥杯省赛C++A组I题) 解题报告(状压dp) xzc 2019/4/5 试题 I: 糖果 时间限制: 1.0s 内存限制: 256.0MB 本题总分:25分 [问题描述]    ...

  8. YbtOJ#20070-[NOIP2020模拟赛B组Day5]诗人小K【状压dp】

    正题 题目链接:http://noip.ybtoj.com.cn/contest/102/problem/4 题目大意 求有多少个长度为nnn的序列aaa满足1≤ai≤101\leq a_i\leq ...

  9. 校赛热身 Problem C. Sometimes Naive (状压dp)

    题解: 列举每一种3的倍数的组合,开始先求出3条边的可行解,则 六条边的可行解可以由两个三条边得来. 详见代码解析 #include<bits/stdc++.h> using namesp ...

  10. 【FZU】Problem 2217 Taxi 【暴力状压dp】

    传送门:[FZU]Problem 2217 Taxi my   code: my~~~code: ///* #include <stdio.h> #include <string.h ...

最新文章

  1. 使用Python和NLTK的自然语言处理(NLP)教程
  2. 谷歌利用人工智能设计的芯片揭示了智能的本质
  3. linux搭建--centos使用qemu-kvm,libvirt搭建虚拟机,并搭建libvmi来虚拟机自省(四)
  4. 天翼云从业认证(4.6)高并发场景上云实践
  5. 2003系统管理实战 web的优化 安全
  6. Python 基础入门--简介和环境配置
  7. 2019.7.29二维数组
  8. Zenlayer完成近亿元A轮融资,欲构建全球连接服务平台
  9. JavaScript 命名空间
  10. html中搜索框提示语,请输入您要搜索的内容(自定义Win10搜索框提示语的技巧)...
  11. win10重置网络命令_WIN10重置网络的操作方法
  12. 儒雅计算机导师,龙桂鲁:儒雅的学者,严慈的良师-清华大学新闻网
  13. 关于移动应用用户体验设计的一些体会
  14. springboot 配置文件的所有属性
  15. 【Java并发编程】闭锁
  16. LeetCode(1292):元素和小于等于阈值的正方形的最大边长 Maximum Side Length of a Square(Java)
  17. 白话自然语言处理(1)之概述
  18. 使用MATLAB绘制分段函数实现
  19. [4750G] 【ubuntu分享帖】acer 4750G ubuntu安装后的一些设置 (ADSL,软件源--最好使用ubuntu默认的源)
  20. hovm什么意思_和超级玩家交朋友:OPPO Ace2 5G手机正式发布,更轻薄的骁龙865旗舰 售价3999元起...

热门文章

  1. ERP实施的焦点依然是实施顾问
  2. Deepin在matlab的安装
  3. html全屏代码怎么写,JS实现全屏的四种写法
  4. python中文件打开的合法模式组合_python中各种文件打开模式
  5. 1059 Prime Factors (25 分)质因子 易错题
  6. php指令,php命令行下的常用命令
  7. python重写和装饰器_Python | 老司机教你 5 分钟读懂 Python 装饰器
  8. linux5.4获取root权限,gcc++漏洞 普通用户获取root权限
  9. e: 无法定位软件包 python-pip_关于Sony镜头不同系列定位的最全面分析
  10. 省赛第七场(fzu1881 ~fzu1889)