LightOJ 1231+1232+1122+1047 (简单dp)
2013-07-15 11:03
197 查看
LightOJ 1231 Coin Change (I)
题目链接 http://lightoj.com/volume_showproblem.php?problem=1231
题意:给你n个物品的体积和数量,让你求有多少种组合能恰好装满M体积的背包。
思路:最开始想的是多重背包和母函数,发现都不太合适。最后还是回归最基本的dp吧。
dp[i][j]表示前i种物品,组成j的容量有几种取法,枚举第i种物品取得数量,注意可以不取。
优化后的代码,效率提高很多:
LightOJ 1231 Coin Change (II)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1232
题意:和上面那道差不多,只是每个最多只能用k次,看起来很麻烦,但其实就是最水的完全背包……
LightOJ 1122 Digit Count
题意:给出数字集合S,求由S中元素构成长度为N且相邻位数字只差不超过2的数字有几个。
Lightoj 1047 Neighbor House
题意:有n户人,打算把他们的房子图上颜色,有red、green、blue三种颜色,每家人涂不同的颜色要花不同的费用,而且相邻两户人家之间的颜色要不同,求最小的总花费费用
题目链接 http://lightoj.com/volume_showproblem.php?problem=1231
题意:给你n个物品的体积和数量,让你求有多少种组合能恰好装满M体积的背包。
思路:最开始想的是多重背包和母函数,发现都不太合适。最后还是回归最基本的dp吧。
dp[i][j]表示前i种物品,组成j的容量有几种取法,枚举第i种物品取得数量,注意可以不取。
#include <cstdio> #include <cstring> int n,sum,v; int dp[55][1005],c[55],num[55]; const int mod=100000007; int main () { int T; scanf("%d",&T); for (int Cas=1;Cas<=T;Cas++) { int i; scanf("%d%d",&n,&v); sum=0; memset(dp,0,sizeof(dp)); for (i=1;i<=n;i++) scanf("%d",&c[i]); for (i=1;i<=n;i++) scanf("%d",&num[i]); for (int ss=1;ss<=n;ss++) for (i=1;i<=num[ss];i++) if (i*c[ss]<=v) dp[ss][i*c[ss]]=1; for (i=2;i<=n;i++) for (int j=1;j<=v;j++) for (int k=0;k<=num[i];k++) if (j-k*c[i]>0) dp[i][j]=(dp[i][j]%mod+dp[i-1][j-k*c[i]]%mod)%mod; printf("Case %d: %d\n",Cas,dp [v]%mod); } return 0; }
优化后的代码,效率提高很多:
#include <cstdio> #include <cstring> int n,v; int dp[55][1005],c[55],num[55]; const int mod=100000007; int main () { int T,i; scanf("%d",&T); for (int Cas=1;Cas<=T;Cas++) { scanf("%d%d",&n,&v); memset(dp,0,sizeof(dp)); for (i=1;i<=n;i++) scanf("%d",&c[i]); for (i=1;i<=n;i++) scanf("%d",&num[i]); dp[0][0]=1; for (i=1;i<=n;i++) for (int j=0;j<=v;j++) for (int k=0;j+k*c[i]<=v && k<=num[i];k++) { dp[i][j+k*c[i]]+=dp[i-1][j]; dp[i][j+k*c[i]]%=mod; } printf("Case %d: %d\n",Cas,dp [v]%mod); } return 0; }
LightOJ 1231 Coin Change (II)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1232
题意:和上面那道差不多,只是每个最多只能用k次,看起来很麻烦,但其实就是最水的完全背包……
#include <cstdio> #include <cstring> #define max(x,y) ((x)>(y)?(x):(y)) const int mod=100000007; int w[105],dp[100005]; int n,v; void CompletePack () { int i,j; memset(dp,0,sizeof(dp)); dp[0]=1; for (i=1;i<=n;i++) for (j=w[i];j<=v;j++) dp[j]=(dp[j]+dp[j-w[i]])%mod; } int main () { int T; scanf("%d",&T); for (int Cas=1;Cas<=T;Cas++) { scanf("%d%d",&n,&v); for (int i=1;i<=n;i++) scanf("%d",&w[i]); CompletePack (); printf("Case %d: %d\n",Cas,dp[v]); } return 0; }
LightOJ 1122 Digit Count
题意:给出数字集合S,求由S中元素构成长度为N且相邻位数字只差不超过2的数字有几个。
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; int dp[12][12]; //dp[i][j] 表示长度为i 以数字data[j]结尾的方案数 int data[12]; int main () { #ifdef ONLINE_JUDGE #else freopen("read.txt","r",stdin); #endif int T,n,m; scanf("%d",&T); for (int Cas=1;Cas<=T;Cas++) { printf("Case %d: ",Cas); memset(dp,0,sizeof(dp)); scanf("%d%d",&m,&n); int i; for (i=1;i<=m;i++) scanf("%d",&data[i]); for (i=1;i<=m;i++) dp[1][i]=1; for (i=2;i<=n;i++) for (int j=1;j<=m;j++) for (int k=1;k<=m;k++) if (abs(data[k]-data[j])<=2) dp[i][j]+=dp[i-1][k]; int ans=0; for (i=1;i<=m;i++) ans+=dp [i]; printf("%d\n",ans); } return 0; }
Lightoj 1047 Neighbor House
题意:有n户人,打算把他们的房子图上颜色,有red、green、blue三种颜色,每家人涂不同的颜色要花不同的费用,而且相邻两户人家之间的颜色要不同,求最小的总花费费用
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <algorithm> using namespace std; #define min(a,b) ((a)<(b)?(a):(b)) #define min3(a,b,c) min((a),min((b),(c))) int data[25][4]; int dp[25][4];//dp[i][j]第i户选j时的最小钱数 int main () { #ifdef ONLINE_JUDGE #else freopen("read.txt","r",stdin); #endif int T; scanf("%d",&T); for (int Cas=1;Cas<=T;Cas++) { int i,n,a,b; scanf("%d",&n); for (i=1;i<=n;i++) scanf("%d%d%d",&data[i][1],&data[i][2],&data[i][3]); memset(dp,0,sizeof(dp)); for (i=1;i<=3;i++) dp[1][i]=data[1][i]; for (i=2;i<=n;i++) for (int j=1;j<=3;j++) { if (j==1) a=2,b=3; if (j==2) a=1,b=3; if (j==3) a=2,b=1; dp[i][j]=data[i][j]+min(dp[i-1][a],dp[i-1][b]); // printf("%d %d %d\n",j,a,b); } int ans=min3(dp [1],dp [2],dp [3]); printf("Case %d: %d\n",Cas,ans); } return 0; }
相关文章推荐
- lightoj1047 【简单线性DP】
- lightoj 1122 - Digit Count 简单DP
- lightoj 1047 - Neighbor House DP(简单线性DP)
- lightoj 1122 - Digit Count 简单DP
- lightoj1231--Coin Change (I)(简单dp,背包计数)
- LightOj 1122 Digit Count(数位dp)
- LightOJ 1047 Neighbor House (线性dp 类数字三角形)
- HDU 1231 (简单DP问题)
- Lightoj 1122 数位DP
- Neighbor House (II) LightOJ - 1217 简单dp(1wa)
- XTU-1231 人生成就(求路径的种类 简单DP)
- LightOJ 1047 - Neighbor House(dp)
- HDU 1231 最大连续子序列 简单dp
- LightOj 1047 Neighbor House(基础dp)
- LightOJ1122 Digit Count(DP)
- LightOJ 1231 Coin Change (I) (线性dp 背包计数)
- LightOJ 1047 Neighbor House (DP 数字三角形变形)
- lightoj 1122 - Digit Count(dp)
- 在博客园安家啦~LightOJ 1004 Monkey Banana Problem (简单DP)
- 1231 - Coin Change (I) (简单DP)