URAL 1244
题目大意:给出一个正整数M,给出N个正整数ai,让你在这些数中挑出一些数组成M的一个划分,如果符合条件的划分数超过两个,输出:-1,如果没有输出:0,如果有且仅有一个:则按顺序输出剩下的数的序号。
例如:
| input | output |
|---|---|
270 |
2 4 |
270 |
-1 |
270 |
0 |
测例1中,有且仅有100+170=270,所以输出110与200的序号2 4。测例2中,100+170=160+110=270,所以输出-1。测例3中,没有任何两个数的和为270,所以输出0。
Time Limit:500MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
数据规模:0<ai<=1000,2<=N<=100。
理论基础:无。
题目分析:我们用dp[i][j]表示仅用前i个数可以挑出的j的划分的个数。pre[i][j]表示第i个数被选择或者未被选择,用于最后输出结果。
我们可以得出如果需要输出时,那么方案数就是唯一的,所以途径的所有的状态的数都只能是被选或者未被选择,所以我们不用担心,a[i]被选与未被选都有解的情况。因为这时我们不需要输出。
下来是状态转移方程:dp[i][j]=dp[i-1][j]+(j>=a[i])*(dp[i-1][j-a[i]]);在每一层dp时,只要发现dp[i][M]大于等于2即可输出-1退出程序。
如果dp[N][M]为0,则输出0。否则,回溯找回答案并输出。
代码如下:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<ctime>
#include<vector>
using namespace std;
typedef double db;
#define DBG 0
#define maa (1<<31)
#define mii ((1<<31)-1)
#define ast(b) if(DBG && !(b)) { printf("%d!!|\n", __LINE__); while(1) getchar(); } //调试
#define dout DBG && cout << __LINE__ << ">>| "
#define pr(x) #x"=" << (x) << " | "
#define mk(x) DBG && cout << __LINE__ << "**| "#x << endl
#define pra(arr, a, b) if(DBG) {\
dout<<#arr"[] |" <<endl; \
for(int i=a,i_b=b;i<=i_b;i++) cout<<"["<<i<<"]="<<arr[i]<<" |"<<((i-(a)+1)%8?" ":"\n"); \
if((b-a+1)%8) puts("");\
}
template<class T> inline bool updateMin(T& a, T b) { return a>b? a=b, true: false; }
template<class T> inline bool updateMax(T& a, T b) { return a<b? a=b, true: false; }
typedef long long LL;
typedef long unsigned int LU;
typedef long long unsigned int LLU;
#define N 100
#define M 100000
int dp[N+1][M+1];
int a[N+1],sum,n,cnt,ans[N+1];
bool pre[N+1][M+1];
int main()
{
scanf("%d%d",&sum,&n);
for(int i=1;i<=n;i++)scanf("%d",a+i);
dp[1][0]=1,dp[1][a[1]]=1,pre[1][a[1]]=true;
for(int i=2;i<=n;i++)
{
for(int j=0;j<=sum;j++)
{
dp[i][j]=dp[i-1][j]+(j>=a[i])*dp[i-1][j-a[i]];
if(dp[i-1][j-a[i]])pre[i][j]=true;
}
if(dp[i][sum]>=2)
{
printf("-1\n");
return 0;
}
}
if(dp[n][sum]==0)
{
printf("0\n");
return 0;
}
if(dp[n][sum]==1)
{
for(int i=n;i>=1;i--)
{
if(!pre[i][sum])ans[++cnt]=i;
sum=sum-a[i]*pre[i][sum];
}
pra(ans,1,cnt)
for(int i=cnt;i>=1;i--)
{
printf("%d%c",ans[i],i==1?'\n':' ');
}
}
return 0;
}
其中的初始化细节处理很容易理解,所以不用再细说了。
by:Jsun_moon http://blog.csdn.net/jsun_moon
URAL 1244的更多相关文章
- DP URAL 1244 Gentlemen
题目传送门 /* 题意:已知丢失若干卡片后剩余的总体积,并知道原来所有卡片的各自的体积,问丢失的卡片的id DP递推:首先从丢失的卡片的总体积考虑,dp[i] 代表体积为i的方案数,从dp[0] = ...
- 递推DP URAL 1244 Gentlemen
题目传送门 /* 题意:给出少了若干卡片后的总和,和原来所有卡片,问少了哪几张 DP:转化为少了的总和是否能有若干张卡片相加得到,dp[j+a[i]] += dp[j]; 记录一次路径,当第一次更新的 ...
- ural 1244. Gentlemen
1244. Gentlemen Time limit: 0.5 secondMemory limit: 64 MB Let's remember one old joke: Once a gentle ...
- URAL 1244. Gentlemen(DP)
题目链接 这题不难啊...标记一下就行了.表示啥想法也没有. #include <cstring> #include <cstdio> #include <string& ...
- URAL 1244. Gentlemen (DP)
题目链接 题意 : 给出一幅不完全的纸牌.算出哪些牌丢失了. 思路 : 算是背包一个吧.if f[j]>0 f[j+a[i]] += f[j];然后在记录一下路径. #include < ...
- URAL DP第一发
列表: URAL 1225 Flags URAL 1009 K-based Numbers URAL 1119 Metro URAL 1146 Maximum Sum URAL 1203 Scient ...
- 【51Nod 1244】莫比乌斯函数之和
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 模板题... 杜教筛和基于质因子分解的筛法都写了一下模板. 杜教筛 ...
- 51nod 1244 莫比乌斯函数之和
题目链接:51nod 1244 莫比乌斯函数之和 题解参考syh学长的博客:http://www.cnblogs.com/AOQNRMGYXLMV/p/4932537.html %%% 关于这一类求积 ...
- 后缀数组 POJ 3974 Palindrome && URAL 1297 Palindrome
题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串 ...
随机推荐
- hdu1074 Doing Homework(状态压缩DP Y=Y)
Doing Homework Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- ajax_post方式
test_ajax_post.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" &quo ...
- GUID的广泛使用
GUID(Global unique identifier)全局唯一标识符,它是由网卡上的标识数字(每个网卡都有唯一的标识号)以及 CPU 时钟的唯一数字生成的的一个 16 字节的二进制值. GUID ...
- java虚拟机涉及内存溢出
Java语言写的代码是.java文件,它会被特定程序编译(javac.exe,它会被Eclipse之类的IDE调用)成字节码(bytecode),字节码不能直接在CPU上运行,需要另一个程序读取并执行 ...
- ORA-19502: write error on file "/u01/app/oracle/oradata/standby/system01.dbf", blockno 40321 (blocksize=8192)【error收集】
在RMAN备份中,出现了一个问题,就是出现坏块了. ORA-: write error on file (blocksize=) ORA-: File I/O error Linux Error: : ...
- UITableView出现卡顿如何处理
tableView的beginUpdate和endUpdate要比reloadData和reloadRowsAtIndexPaths好,因为beginUpdate和endUpdate会执行一个动画bl ...
- php学习之路
1.php拼接字符串+查询 $floor_id = M('house_floor_input')->where($map1)->field('id')->select(); $flo ...
- 总结:如何获取同一个DIV里的多个不同子标签的值,并赋值给input?
这个问题说起来简单,但对于新手来说,也着实卡了好久,并且我在网上搜了好久没能找到合适的答案, 于是去博问问了一下,得到许多大神们的帮助与回答,接下来我就总结一下能够实现这个效果的几种方法,既为了自己更 ...
- javascript代码放置位置对程序的影响
在编写html文档时,javascript可以放置的位置有两个地方<head>或者<body>,但是放置的地方,会对 JavaScript 代码的正常执行会有一定影响.由于 H ...
- Linux(Centos)之安装tomcat并且部署Java Web项目(转)
1.准备工作 a.下载tomcat linux的包,地址:http://tomcat.apache.org/download-80.cgi,我们下载的版本是8.0,下载方式如图: b ...