poj 1837 dp

来源:互联网 发布:美白补水面膜 知乎 编辑:程序博客网 时间:2024/05/16 15:37

2015/2.12


简单的背包dp....要注意的是挂砝码的过程中会出现平衡度为负数的情况,所以要用数组右移的方式防止数组越界。

for ->放第 i 砝码

for ->遍历平衡度(当前砝码放下后的平衡度是根据前一个平衡度状态来变化的 )

for->第 i 个砝码 放在不同位子上的时候天平平衡度的变化。

整个过程根据天平平衡度来变化,一开始天平平衡,所以初始状态就是 dp[ 0 ][ 8000 ] = 1;

平衡度的范围 是 20*20*15  ~ 8000,再考虑到对称性,我开了数组的大小是16000,那么天平的平衡点就是 8000,dp[ 0 ][ 8000 ]  = 1表示 (一开始)天平平衡状态存在

接下去就是不停的放砝码的过程,等到砝码全部放完后 dp[砝码数] [8000 ] 就是所求的平衡状态的数量了。 



#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#include<climits>#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;  #define mod 10007#define lson pos<<1,l,mid#define sc(n) scanf("%d",&n)#define rson pos<<1|1,mid+1,r#define pr(n) printf("%d\n",n)#define met(n,m) memset(n, m, sizeof(n))#define F(x,y,i) for(int i = x;i > y; i--)#define f(x,y,i) for(int i = x;i < y; i++)#define ff(x,y,i) for(int i = x;i <= y; i++)#define FF(x,y,i) for(int i = x;i >= y; i--) const int N=100500;const int inf = INT_MAX;int Max(int a,int b){return a>b?a:b;}int Min(int a,int b){return  a<b?a:b;}int a[25];int s[25];int dp[25][16001];int main()  {      int n, m, tot, x;    while(~scanf("%d%d",&n,&m))    {    f(1,n+1,i)    sc(a[i]);        f(1,m+1,i)    sc(s[i]);        met(dp,0);    dp[0][8000] = 1;f(1,m+1,i)f(0,16001,j){if(dp[i-1][j]){f(1,n+1,k)dp[i][j + s[i] * a[k]] += dp[i-1][j];}}    printf("%d\n",dp[m][8000]);    }    return 0;  }  


0 0
原创粉丝点击